Closure-compiler: Unknown type when accessing string in array-like fashion

Created on 16 Jan 2020  路  4Comments  路  Source: google/closure-compiler

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).

bug

All 4 comments

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 String should be IArrayLike<string>?

In the context of accessing characters, EMCAScript strings may be viewed as either

  1. iterable sequences of characters from the _Full Unicode_ set, including

    • characters from the Basic Multilingual Plane (BMP), and

    • characters from the Supplementary Planes (e.g. modern musical notation; mathematical alphanumerics; Emoji and other pictographic sets)

  2. _array-like_ sequences of characters and surrogates from the BMP, including

    • characters from the Basic Multilingual Plane (BMP), and



      • isolated high and low surrogate code units



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).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JohannBlake picture JohannBlake  路  3Comments

ChadKillingsworth picture ChadKillingsworth  路  5Comments

lauraharker picture lauraharker  路  5Comments

joscha picture joscha  路  5Comments

jleyba picture jleyba  路  7Comments