使用Closure Compiler,Array <t>注释与Array只有什么好处?

时间:2015-10-28 15:20:39

标签: javascript google-closure-compiler google-closure typechecking

我预计Closure Compiler会对下面的所有行发出警告,但只有3)显示为问题。 Type Checking Array Contents with Closure-Compiler触及了同一点,但我的问题是,鉴于这些限制,通过注释Array<T>Array实现了哪些好处?我觉得这是一种虚假的安全感。

// ==ClosureCompiler==
// @compilation_level SIMPLE_OPTIMIZATIONS
// @output_file_name default.js
// @warning_level VERBOSE
// ==/ClosureCompiler==

/** @type {!Array<!string>} */
var xs = [];
xs.push(42);       // 1) no warning
xs.push(null);     // 2) no warning
xs = 'foo'         // 3) warns - found: string, required: Array<string>
xs = [1,2,3];      // 4) no warning

快速修改:您可以在http://closure-compiler.appspot.com/

处使用此代码

2 个答案:

答案 0 :(得分:1)

我怀疑这是因为externs definition for Array.prototype.push不太正确。如果删除@this类型,则应该会收到预期的错误。据推测,{length: number}部分由于某种原因被添加,因此删除它可能会破坏某些现有代码。

答案 1 :(得分:0)

与其他静态语言一样,您将获得与泛型相同的好处 假设您要创建一个字符串数组,然后使用它们的长度对它们进行排序。

var arr = [];    
arr.sort(function(a, b) { return a.length - b.length; });

如果您将数组注释为Array,那么您将能够向数组添加一个数字,并且闭包编译器不会抱怨。
最终您会遇到异常,因为数字没有长度属性 如果您将数组注释为字符串数组Array<string>,那么您将确保length属性存在,并且没有人能够插入除字符串之外的任何其他类型。

我不知道为什么你没有使用字符串编译错误,但如果你用数字编写它会得到不同的编译结果。

// ==ClosureCompiler==
// @compilation_level SIMPLE_OPTIMIZATIONS
// @output_file_name default.js
// @warning_level VERBOSE
// ==/ClosureCompiler==

/** @type {!Array<!number>} */
var xs = [];
xs.push(42);
console.log(xs[0].length);

=> 
Number of warnings: 1

JSC_INEXISTENT_PROPERTY: Property length never defined on Number at line 4 character 18
console.log(xs[0].length);
              ^