Merge pull request #18029 from Microsoft/allow-string-enum-in-element-access

Allow string enum in element access
This commit is contained in:
Nathan Shively-Sanders 2017-08-28 12:56:08 -07:00 committed by GitHub
commit 278dcc6fac
5 changed files with 129 additions and 1 deletions

View file

@ -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 (<UnionType>indexType).types) {
const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false);

View file

@ -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];

View file

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

View file

@ -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

View file

@ -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];