我预计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/
处使用此代码答案 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);
^