Reputation: 558
I sometimes run into the situation that I have a JavaScript object of unknown type. Then I perform a type check in script and call appropriate functions depending on the detected type. e.g. like this
/**
* @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);
}
}
Running this sniplet via advanced compilation in the google closure compiler yields the following warning message:
JSC_TYPE_MISMATCH: actual parameter 1 of actOnArray does not match formal parameter
found : *
required: Array at line 14 character 15
actOnArray(aObject);
This warning makes sense, since the compiler does not know anything about the semantic of my type check.
My question is: how can I annotate the code to tell the compiler that at a certain point I have gained information about a type. In this example I would like to tell inside the if block that I now know for sure that the aObject parameter is of type !Array.
Upvotes: 1
Views: 103
Reputation: 14411
For some patterns, the compiler can automatically tighten the types within tests:
// ==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]);
However, in many cases it cannot. In those instances you need to type cast:
actOnArray(/** @type {!Array} */ (aObject));
note the extra parenthesis - they are required
Upvotes: 1