google closure的typedef实际上做了什么?

时间:2011-08-15 08:59:53

标签: javascript google-closure jsdoc

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

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

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

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

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

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

/**
 * @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'attr。使用typedef只需更新typedef声明,而不是整个代码库中的每个内联类型声明。

另见Using Google Closure's @typedef tag

答案 2 :(得分:0)

它不仅用于文档。当您使用闭包编译器编译脚本时,它还会发出警告。

  

Closure Compiler可以使用有关JavaScript的数据类型信息   变量提供增强的优化和警告。 JavaScript中,   但是,无法声明类型。

答案 3 :(得分:0)

如果在注释中定义整个typedef会更好。将其部分定义为代码会带来一些意想不到的后果。参见此blog post

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