The following code produces no warning despite the type mismatch on the second line:
var c = "abc"[1];
var /**number*/ n = c; // no warning
It looks like getting a character from a string in this way produces a value of unknown type (I have confirmed this by turning reportUnknownTypes on).
Thanks for the report.
You can also verify that "abc"[1] is an unknown type in the debugger. The generated AST + type annotations is
SCRIPT 1 [length: 56] [source_file: input0] [input_id: InputId: input0] [feature_set: []]
VAR 1 [length: 17] [source_file: input0]
NAME c 1 [length: 12] [source_file: input0] [constant_var_flags: 2] : ?
GETELEM 1 [length: 8] [source_file: input0] : ?
STRING abc 1 [length: 5] [source_file: input0] : string
NUMBER 1.0 1 [length: 1] [source_file: input0] : number
I forgot to mention that Steve Hicks already diagnosed this problem here:
https://groups.google.com/forum/#!topic/closure-compiler-discuss/5PG-kVIPyoM
I hope this helps.
Perhaps String should be IArrayLike<string>?
Perhaps
Stringshould beIArrayLike<string>?
In the context of accessing characters, EMCAScript strings may be viewed as either
The _Full Unicode_ view might be preferred as all Unicode characters are treated consistently without any need to explicitly handle surrogate code units. However, many people habitually take the _array-like_ view: sometimes because it is appropriate; but frequently out of ignorance. In the latter case, often scripts fail to correctly handle strings that include surrogate code units.
For example, I prefer the first two of these alternatives and choose to avoid string.split("")
1. for (const fullUnicodeCharacter of string) {...}
2. Array.from(string, fullUnicodeCharacter => {...}).join("");
3. string.split("").forEach(bmpCharacterOrIsolatedSurrogate => {...});
4. string.split("").map(bmpCharacterOrIsolatedSurrogate => {...}).join("");
It may be considered desirable by some, including myself, to encourage the _Full Unicode_ view and discourage the _array-like_ view (unless appropriate).