diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d671d0e558..bebd354d25 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7685,8 +7685,10 @@ namespace ts { return type; } // In the following we resolve T[K] to the type of the property in T selected by K. + // We treat boolean as different from other unions to improve errors; + // skipping straight to getPropertyTypeForIndexType gives errors with 'boolean' instead of 'true'. const apparentObjectType = getApparentType(objectType); - if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Primitive)) { + if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Boolean)) { const propTypes: Type[] = []; for (const t of (indexType).types) { const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false); diff --git a/tests/baselines/reference/stringEnumInElementAccess01.js b/tests/baselines/reference/stringEnumInElementAccess01.js new file mode 100644 index 0000000000..6dadb919a3 --- /dev/null +++ b/tests/baselines/reference/stringEnumInElementAccess01.js @@ -0,0 +1,26 @@ +//// [stringEnumInElementAccess01.ts] +enum E { + A = "a", + B = "b", + C = "c", +} + +interface Item { + a: string; + b: number; + c: boolean; +} + +declare const item: Item; +declare const e: E; +const snb: string | number | boolean = item[e]; + + +//// [stringEnumInElementAccess01.js] +var E; +(function (E) { + E["A"] = "a"; + E["B"] = "b"; + E["C"] = "c"; +})(E || (E = {})); +var snb = item[e]; diff --git a/tests/baselines/reference/stringEnumInElementAccess01.symbols b/tests/baselines/reference/stringEnumInElementAccess01.symbols new file mode 100644 index 0000000000..337edf1d59 --- /dev/null +++ b/tests/baselines/reference/stringEnumInElementAccess01.symbols @@ -0,0 +1,40 @@ +=== tests/cases/conformance/expressions/elementAccess/stringEnumInElementAccess01.ts === +enum E { +>E : Symbol(E, Decl(stringEnumInElementAccess01.ts, 0, 0)) + + A = "a", +>A : Symbol(E.A, Decl(stringEnumInElementAccess01.ts, 0, 8)) + + B = "b", +>B : Symbol(E.B, Decl(stringEnumInElementAccess01.ts, 1, 12)) + + C = "c", +>C : Symbol(E.C, Decl(stringEnumInElementAccess01.ts, 2, 12)) +} + +interface Item { +>Item : Symbol(Item, Decl(stringEnumInElementAccess01.ts, 4, 1)) + + a: string; +>a : Symbol(Item.a, Decl(stringEnumInElementAccess01.ts, 6, 16)) + + b: number; +>b : Symbol(Item.b, Decl(stringEnumInElementAccess01.ts, 7, 14)) + + c: boolean; +>c : Symbol(Item.c, Decl(stringEnumInElementAccess01.ts, 8, 14)) +} + +declare const item: Item; +>item : Symbol(item, Decl(stringEnumInElementAccess01.ts, 12, 13)) +>Item : Symbol(Item, Decl(stringEnumInElementAccess01.ts, 4, 1)) + +declare const e: E; +>e : Symbol(e, Decl(stringEnumInElementAccess01.ts, 13, 13)) +>E : Symbol(E, Decl(stringEnumInElementAccess01.ts, 0, 0)) + +const snb: string | number | boolean = item[e]; +>snb : Symbol(snb, Decl(stringEnumInElementAccess01.ts, 14, 5)) +>item : Symbol(item, Decl(stringEnumInElementAccess01.ts, 12, 13)) +>e : Symbol(e, Decl(stringEnumInElementAccess01.ts, 13, 13)) + diff --git a/tests/baselines/reference/stringEnumInElementAccess01.types b/tests/baselines/reference/stringEnumInElementAccess01.types new file mode 100644 index 0000000000..f0e878f776 --- /dev/null +++ b/tests/baselines/reference/stringEnumInElementAccess01.types @@ -0,0 +1,44 @@ +=== tests/cases/conformance/expressions/elementAccess/stringEnumInElementAccess01.ts === +enum E { +>E : E + + A = "a", +>A : E.A +>"a" : "a" + + B = "b", +>B : E.B +>"b" : "b" + + C = "c", +>C : E.C +>"c" : "c" +} + +interface Item { +>Item : Item + + a: string; +>a : string + + b: number; +>b : number + + c: boolean; +>c : boolean +} + +declare const item: Item; +>item : Item +>Item : Item + +declare const e: E; +>e : E +>E : E + +const snb: string | number | boolean = item[e]; +>snb : string | number | boolean +>item[e] : string | number | boolean +>item : Item +>e : E + diff --git a/tests/cases/conformance/expressions/elementAccess/stringEnumInElementAccess01.ts b/tests/cases/conformance/expressions/elementAccess/stringEnumInElementAccess01.ts new file mode 100644 index 0000000000..2dc07cb0e4 --- /dev/null +++ b/tests/cases/conformance/expressions/elementAccess/stringEnumInElementAccess01.ts @@ -0,0 +1,16 @@ +// @noImplicitAny: true +enum E { + A = "a", + B = "b", + C = "c", +} + +interface Item { + a: string; + b: number; + c: boolean; +} + +declare const item: Item; +declare const e: E; +const snb: string | number | boolean = item[e];