在使用Google Closure Compiler时,我发现了一个案例,我无法强制编译器对错误的变量类型发出警告。我使用了以下示例:
/** @typedef ({name: string, token: string}) */
var pendingItem;
/** @type (Array.<pendingItem>) */
var pending = [];
// NOTICE: the token is intentionally misspelled as "toke" to cause a warning
var dummyItem = {
name: 'NameHere',
toke: 'SomeToken'
};
// This should cause a warning, because of the
// type mismatch (toke instead of token)
pending.push(dummyItem);
// Do something useful so that the whole code wouldn't be optimized to 0 bytes
alert(pending.length);
它完美编译,而不是给出预期的类型警告。但是如果你使用:
pending[1] = {
name: 'Second Name',
toke: 'Second Token'
}
您收到预期的类型不匹配警告。
我理解这可能是因为push
没有定义类型检查,因为它是一个内置函数。可以预期将pending
定义为pendingItem
的数组会强制它,但默认情况下不会。
问题是是否以及如何将类型检查添加到已定义的函数(例如push
)中,以便在上面的示例中给出警告。我也理解,实现类似结果的一种方法是在/** @type {pendingItem} */
之前添加dummyItem
来强制类型,但出于教育目的,我想知道如何向{{{{{{ 1}}(或者可能更严格地定义push
本身)。
还有人可以解释重命名对象属性背后的逻辑吗?如果您编译上面的示例,则不会重命名pending
的属性dummyItem
,但会将name
重命名为token
。
答案 0 :(得分:2)
要强制检查push
,必须在代码中使用正确的类型重新定义。请注意,使用对象文字表示法,您必须使用@type
而不是@param
来定义类型,因为我们将函数分配给对象的参数,而不是定义普通函数。在这种情况下,它将是以下内容:
/** @type {function(pendingItem)} */
pending.push = function(item) {
Array.prototype.push.call(pending, item);
};
现在尝试编译以下内容时:
// Still an intentionally misspelled "toke"
var dummyItem = {
name: 'NameHere',
toke: 'SomeToken'
};
// First warning
pending.push(dummyItem);
// Second warning
pending[1] = {
name: 'Second name',
toke: 'Second Token'
};
然后两者都会产生类型不匹配警告,就像预期的那样。
认为将来可能对某人有用。