Google 闭包编译器中的动态类型发现
Dynamic type discovery in Google Closure Compiler
我有时 运行 遇到这样的情况,我有一个 JavaScript 未知类型的对象。然后我在脚本中执行类型检查并根据检测到的类型调用适当的函数。
例如像这样
/**
* @param {!Array} aArray my array
*/
function actOnArray(aArray) {
}
/**
* @param {*} aObject an arbitrary object
*/
function doSomething(aObject) {
// make sure we have an array
if ((null != aObject) && Array.isArray(aObject)) {
actOnArray(aObject);
}
}
运行 此代码片段通过 google 闭包编译器中的高级编译产生以下警告消息:
JSC_TYPE_MISMATCH: actual parameter 1 of actOnArray does not match formal parameter
found : *
required: Array at line 14 character 15
actOnArray(aObject);
这个警告是有道理的,因为编译器对我的类型检查的语义一无所知。
我的问题是:我如何注释代码以告诉编译器在某个时刻我获得了有关类型的信息。在此示例中,我想在 if 块中告诉我现在确定 aObject 参数的类型为 !Array.
对于某些模式,编译器可以自动收紧测试中的类型:
// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name default.js
// @warning_level VERBOSE
// ==/ClosureCompiler==
/** @param {*} data */
function log(data) {
if (data && data instanceof Array) {
logArray(data);
} else {
console.log(data);
}
}
/** @param {!Array} data */
function logArray(data) {
for(var i = 0; i < data.length; i++) {
log(data[i]);
}
}
log([1, 2, 3]);
然而,在很多情况下它不能。在这些情况下,您需要键入 cast:
actOnArray(/** @type {!Array} */ (aObject));
注意额外的括号 - 它们是必需的
我有时 运行 遇到这样的情况,我有一个 JavaScript 未知类型的对象。然后我在脚本中执行类型检查并根据检测到的类型调用适当的函数。 例如像这样
/**
* @param {!Array} aArray my array
*/
function actOnArray(aArray) {
}
/**
* @param {*} aObject an arbitrary object
*/
function doSomething(aObject) {
// make sure we have an array
if ((null != aObject) && Array.isArray(aObject)) {
actOnArray(aObject);
}
}
运行 此代码片段通过 google 闭包编译器中的高级编译产生以下警告消息:
JSC_TYPE_MISMATCH: actual parameter 1 of actOnArray does not match formal parameter
found : *
required: Array at line 14 character 15
actOnArray(aObject);
这个警告是有道理的,因为编译器对我的类型检查的语义一无所知。
我的问题是:我如何注释代码以告诉编译器在某个时刻我获得了有关类型的信息。在此示例中,我想在 if 块中告诉我现在确定 aObject 参数的类型为 !Array.
对于某些模式,编译器可以自动收紧测试中的类型:
// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name default.js
// @warning_level VERBOSE
// ==/ClosureCompiler==
/** @param {*} data */
function log(data) {
if (data && data instanceof Array) {
logArray(data);
} else {
console.log(data);
}
}
/** @param {!Array} data */
function logArray(data) {
for(var i = 0; i < data.length; i++) {
log(data[i]);
}
}
log([1, 2, 3]);
然而,在很多情况下它不能。在这些情况下,您需要键入 cast:
actOnArray(/** @type {!Array} */ (aObject));
注意额外的括号 - 它们是必需的