【问题标题】:What does google closure's typedef actually do?google 闭包的 typedef 实际上是做什么的?
【发布时间】:2018-12-24 15:45:36
【问题描述】:

我了解它的用途 - 我可以看到能够为复杂类型定义别名并在文档中使用它的好处。所以你可以定义一个类型...

/** @typedef {{x:number, y:number}} */
example.Point;

...然后用它来记录一个函数,比如...

/**
 * @param {example.Point} point
 * @return {example.Point}
 */
example.functionThatTakesAPointAndReturnsAPoint(point) {
....
}

但我不确定的是,如果它只用于文档和编译器的静态类型检查,那么为什么 typedef 需要那行 JavaScript?别名不能完全在文档注释块中定义吗?而且,如果您直接提供代码(不编译它),JavaScript 解释器会如何处理 typedef 注释之后的那行代码?

【问题讨论】:

    标签: javascript google-closure jsdoc


    【解决方案1】:

    编译器建立在 Rhino 之上,只是增强了可用的语法。我认为从无操作属性访问中获取别名更容易,因为它符合标准模式。

    【讨论】:

    • 谢谢 - 我想这就是我正在寻找的信息。所以 typedef 之后的那行 JavaScript 什么都不做……而且基本上是为了方便而以这种方式实现的。
    【解决方案2】:

    您实际上可以直接在方法文档中设置类型声明:

    /**
     * @param {{x:number, y:number}} pointLike
     */
    var myFn = function(pointLike) {
     return pointLike.x + ':' + pointLike.y;
    }
    
    alert(myFn({x:34, y:20}))
    alert(myFn({x:34, y:'20'})) // will trigger compile time type warning
    

    为您在多个地方使用的对象类型使用 @typedef 的好处在于可用性/清晰度。

    例如:也许你很快就会得到一个“Point.z”属性。使用 typedef,您只需更新 typedef 声明,而不是整个代码库中的每个内联类型声明。

    另见Using Google Closure's @typedef tag

    【讨论】:

      【解决方案3】:

      它不仅用于文档。当你使用闭包编译器编译你的脚本时,它也会给你警告。

      闭包编译器可以使用关于 JavaScript 的数据类型信息 变量以提供增强的优化和警告。 JavaScript, 但是,无法声明类型。

      【讨论】:

      • 谢谢 - 我明白了......我只是有点困惑为什么它需要那行 JavaScript 代码来做到这一点。例如,为什么 typedef 不能只是像 /** @typedef {{x:number, y:number}} example.Point */ 这样的东西。我对 JavaScript 还很陌生,所以我只是想确保那里没有发生我无法正确理解的事情。
      【解决方案4】:

      如果整个 typedef 在注释中定义会更好。将其中的一部分定义为代码会产生一些意想不到的后果。看到这个blog post

      在实际代码中定义 typedef 名称的原因是 Closure Compiler 中解析和类型检查的工作方式。解析器需要将每个 jsdoc 注释附加到一个 AST 节点,否则注释会被静默忽略。因此,typedef 的名称被定义为 code,jsdoc 附加到它上面,然后 typechecker 会选择类型定义。

      【讨论】:

        猜你喜欢
        • 2011-03-11
        • 2010-11-26
        • 2015-06-23
        • 2017-12-26
        • 2016-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多