简体   繁体   中英

Type Checking Array Contents with Closure-Compiler

In Google Closure, if an Array of a specific @type {Array.<type>} is initialized, can I be sure that Google Closure will confirm the Array contents?

Here is a small test case. It appears to me that an {Array.<string>} is sneaking past an {Array.<number>} check, although a {string} is correctly blocked by the same check. I am a little new to GC, is this an error on my part?

I've pasted this to the Google Closure Service , and I'm showing only one of two expected errors (Sept 12 2013). I've double-tested this on my local jar file (newest, v20130823) with ADVANCED_OPTIMIZATIONS and warning_level VERBOSE . It still looks like the {Array.<string>} sneaks by.

Docs: Annotating for Google Closure

Thanks in advance for your input.

// ==ClosureCompiler==
// @output_file_name default.js
// @compilation_level ADVANCED_OPTIMIZATIONS
// @warning_level VERBOSE
// @language ECMASCRIPT5
// ==/ClosureCompiler==

/**
    no warning, as expected:
    @type {Array.<number>}
*/
var a = [1,2,3,4];

/**
    warning! Type mismatch as expected:
    @type {Array.<number>}
*/
var b = 'mismatch';    // {string} does not match {Array.<number>}

/**
    no warning, but Type mismatch was expected:
    @type {Array.<number>}
*/
var c = ['foo','bar']; // {Array.<string>} should not match {Array.<number>}


// prevent compile-to-zero
alert(a);
alert(b);
alert(c);

note: I've taken a close look at this related question , where the type of Array.push() was manually filled in. This question concerns initialization, though. If I take his corrected code and init all of his arrays with garbage data, as above, GC fails to catch the garbage in his case as well.

Edited: added warning_level VERBOSE and language ECMASCRIPT5 to the header on the test case, just to be sure. {Array.<string>} still not detected.

This is a limitation of the current type checker. The right had side is typed as " Array " (aka Array<?> ) not " Array<number> " or " Array<string> " respectively, which is allowed to be assigned to any type.

It is possible to enhance to type type checker for this specific case, but it quickly breaks down in more complex cases due to the fact arrays are mutable in JavaScript. That is if "[11]" were typed to Array<number> then adding any other type would be illegal but arrays are generally not homogeneous consider:

var args = [];
args[0] = 1;
args[1] = 'foo';

So the type of Array must not be limited to initial type by default.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM