Merge pull request #31687 from microsoft/enumImplicitIndexSignatures

Implicit index signatures for enum object types
This commit is contained in:
Anders Hejlsberg 2019-06-02 07:42:58 -07:00 committed by GitHub
commit a5281ada54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 165 additions and 6 deletions

View File

@ -7316,7 +7316,8 @@ namespace ts {
stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
}
}
const numberIndexInfo = symbol.flags & SymbolFlags.Enum ? enumNumberIndexInfo : undefined;
const numberIndexInfo = symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum ||
some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike))) ? enumNumberIndexInfo : undefined;
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
// We resolve the members before computing the signatures because a signature may use
// typeof with a qualified name expression that circularly references the type we are
@ -8194,6 +8195,9 @@ namespace ts {
propTypes.push(getTypeOfSymbol(prop));
}
}
if (kind === IndexKind.String) {
append(propTypes, getIndexTypeOfType(type, IndexKind.Number));
}
if (propTypes.length) {
return getUnionType(propTypes, UnionReduction.Subtype);
}
@ -14615,7 +14619,7 @@ namespace ts {
* with no call or construct signatures.
*/
function isObjectTypeWithInferableIndex(type: Type) {
return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.ValueModule)) !== 0 &&
return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.Enum | SymbolFlags.ValueModule)) !== 0 &&
!typeHasCallOrConstructSignatures(type);
}

View File

@ -44,6 +44,18 @@ function f4() {
const v3 = getNumberIndexValue(o1);
const v4 = getNumberIndexValue(o2);
}
function f5() {
enum E1 { A, B }
enum E2 { A = "A", B = "B" }
enum E3 { A = 0, B = "B" }
const v1 = getStringIndexValue(E1);
const v2 = getStringIndexValue(E2);
const v3 = getStringIndexValue(E3);
const v4 = getNumberIndexValue(E1);
const v5 = getNumberIndexValue(E2);
const v6 = getNumberIndexValue(E3);
}
//// [implicitIndexSignatures.js]
@ -83,3 +95,26 @@ function f4() {
var v3 = getNumberIndexValue(o1);
var v4 = getNumberIndexValue(o2);
}
function f5() {
var E1;
(function (E1) {
E1[E1["A"] = 0] = "A";
E1[E1["B"] = 1] = "B";
})(E1 || (E1 = {}));
var E2;
(function (E2) {
E2["A"] = "A";
E2["B"] = "B";
})(E2 || (E2 = {}));
var E3;
(function (E3) {
E3[E3["A"] = 0] = "A";
E3["B"] = "B";
})(E3 || (E3 = {}));
var v1 = getStringIndexValue(E1);
var v2 = getStringIndexValue(E2);
var v3 = getStringIndexValue(E3);
var v4 = getNumberIndexValue(E1);
var v5 = getNumberIndexValue(E2);
var v6 = getNumberIndexValue(E3);
}

View File

@ -168,3 +168,52 @@ function f4() {
>o2 : Symbol(o2, Decl(implicitIndexSignatures.ts, 39, 7))
}
function f5() {
>f5 : Symbol(f5, Decl(implicitIndexSignatures.ts, 44, 1))
enum E1 { A, B }
>E1 : Symbol(E1, Decl(implicitIndexSignatures.ts, 46, 15))
>A : Symbol(E1.A, Decl(implicitIndexSignatures.ts, 47, 13))
>B : Symbol(E1.B, Decl(implicitIndexSignatures.ts, 47, 16))
enum E2 { A = "A", B = "B" }
>E2 : Symbol(E2, Decl(implicitIndexSignatures.ts, 47, 20))
>A : Symbol(E2.A, Decl(implicitIndexSignatures.ts, 48, 13))
>B : Symbol(E2.B, Decl(implicitIndexSignatures.ts, 48, 22))
enum E3 { A = 0, B = "B" }
>E3 : Symbol(E3, Decl(implicitIndexSignatures.ts, 48, 32))
>A : Symbol(E3.A, Decl(implicitIndexSignatures.ts, 49, 13))
>B : Symbol(E3.B, Decl(implicitIndexSignatures.ts, 49, 20))
const v1 = getStringIndexValue(E1);
>v1 : Symbol(v1, Decl(implicitIndexSignatures.ts, 50, 9))
>getStringIndexValue : Symbol(getStringIndexValue, Decl(implicitIndexSignatures.ts, 11, 13))
>E1 : Symbol(E1, Decl(implicitIndexSignatures.ts, 46, 15))
const v2 = getStringIndexValue(E2);
>v2 : Symbol(v2, Decl(implicitIndexSignatures.ts, 51, 9))
>getStringIndexValue : Symbol(getStringIndexValue, Decl(implicitIndexSignatures.ts, 11, 13))
>E2 : Symbol(E2, Decl(implicitIndexSignatures.ts, 47, 20))
const v3 = getStringIndexValue(E3);
>v3 : Symbol(v3, Decl(implicitIndexSignatures.ts, 52, 9))
>getStringIndexValue : Symbol(getStringIndexValue, Decl(implicitIndexSignatures.ts, 11, 13))
>E3 : Symbol(E3, Decl(implicitIndexSignatures.ts, 48, 32))
const v4 = getNumberIndexValue(E1);
>v4 : Symbol(v4, Decl(implicitIndexSignatures.ts, 53, 9))
>getNumberIndexValue : Symbol(getNumberIndexValue, Decl(implicitIndexSignatures.ts, 13, 68))
>E1 : Symbol(E1, Decl(implicitIndexSignatures.ts, 46, 15))
const v5 = getNumberIndexValue(E2);
>v5 : Symbol(v5, Decl(implicitIndexSignatures.ts, 54, 9))
>getNumberIndexValue : Symbol(getNumberIndexValue, Decl(implicitIndexSignatures.ts, 13, 68))
>E2 : Symbol(E2, Decl(implicitIndexSignatures.ts, 47, 20))
const v6 = getNumberIndexValue(E3);
>v6 : Symbol(v6, Decl(implicitIndexSignatures.ts, 55, 9))
>getNumberIndexValue : Symbol(getNumberIndexValue, Decl(implicitIndexSignatures.ts, 13, 68))
>E3 : Symbol(E3, Decl(implicitIndexSignatures.ts, 48, 32))
}

View File

@ -196,3 +196,62 @@ function f4() {
>o2 : { 0: string; 1: string; count: number; }
}
function f5() {
>f5 : () => void
enum E1 { A, B }
>E1 : E1
>A : E1.A
>B : E1.B
enum E2 { A = "A", B = "B" }
>E2 : E2
>A : E2.A
>"A" : "A"
>B : E2.B
>"B" : "B"
enum E3 { A = 0, B = "B" }
>E3 : E3
>A : E3.A
>0 : 0
>B : E3.B
>"B" : "B"
const v1 = getStringIndexValue(E1);
>v1 : string | E1
>getStringIndexValue(E1) : string | E1
>getStringIndexValue : <T>(map: { [x: string]: T; }) => T
>E1 : typeof E1
const v2 = getStringIndexValue(E2);
>v2 : E2
>getStringIndexValue(E2) : E2
>getStringIndexValue : <T>(map: { [x: string]: T; }) => T
>E2 : typeof E2
const v3 = getStringIndexValue(E3);
>v3 : string | E3.A
>getStringIndexValue(E3) : string | E3.A
>getStringIndexValue : <T>(map: { [x: string]: T; }) => T
>E3 : typeof E3
const v4 = getNumberIndexValue(E1);
>v4 : string
>getNumberIndexValue(E1) : string
>getNumberIndexValue : <T>(map: { [x: number]: T; }) => T
>E1 : typeof E1
const v5 = getNumberIndexValue(E2);
>v5 : unknown
>getNumberIndexValue(E2) : unknown
>getNumberIndexValue : <T>(map: { [x: number]: T; }) => T
>E2 : typeof E2
const v6 = getNumberIndexValue(E3);
>v6 : string
>getNumberIndexValue(E3) : string
>getNumberIndexValue : <T>(map: { [x: number]: T; }) => T
>E3 : typeof E3
}

View File

@ -121,16 +121,16 @@ enum E { A, B }
>B : E.B
var entries5 = Object.entries(E); // [string, any][]
>entries5 : [string, any][]
>Object.entries(E) : [string, any][]
>entries5 : [string, string | E][]
>Object.entries(E) : [string, string | E][]
>Object.entries : { <T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][]; (o: {}): [string, any][]; }
>Object : ObjectConstructor
>entries : { <T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][]; (o: {}): [string, any][]; }
>E : typeof E
var values5 = Object.values(E); // any[]
>values5 : any[]
>Object.values(E) : any[]
>values5 : (string | E)[]
>Object.values(E) : (string | E)[]
>Object.values : { <T>(o: { [s: string]: T; } | ArrayLike<T>): T[]; (o: {}): any[]; }
>Object : ObjectConstructor
>values : { <T>(o: { [s: string]: T; } | ArrayLike<T>): T[]; (o: {}): any[]; }

View File

@ -43,3 +43,15 @@ function f4() {
const v3 = getNumberIndexValue(o1);
const v4 = getNumberIndexValue(o2);
}
function f5() {
enum E1 { A, B }
enum E2 { A = "A", B = "B" }
enum E3 { A = 0, B = "B" }
const v1 = getStringIndexValue(E1);
const v2 = getStringIndexValue(E2);
const v3 = getStringIndexValue(E3);
const v4 = getNumberIndexValue(E1);
const v5 = getNumberIndexValue(E2);
const v6 = getNumberIndexValue(E3);
}