Skip to content

Commit a5281ad

Browse files
authored
Merge pull request #31687 from microsoft/enumImplicitIndexSignatures
Implicit index signatures for enum object types
2 parents d6c323a + bb15df3 commit a5281ad

File tree

6 files changed

+165
-6
lines changed

6 files changed

+165
-6
lines changed

src/compiler/checker.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7316,7 +7316,8 @@ namespace ts {
73167316
stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
73177317
}
73187318
}
7319-
const numberIndexInfo = symbol.flags & SymbolFlags.Enum ? enumNumberIndexInfo : undefined;
7319+
const numberIndexInfo = symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum ||
7320+
some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike))) ? enumNumberIndexInfo : undefined;
73207321
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
73217322
// We resolve the members before computing the signatures because a signature may use
73227323
// typeof with a qualified name expression that circularly references the type we are
@@ -8194,6 +8195,9 @@ namespace ts {
81948195
propTypes.push(getTypeOfSymbol(prop));
81958196
}
81968197
}
8198+
if (kind === IndexKind.String) {
8199+
append(propTypes, getIndexTypeOfType(type, IndexKind.Number));
8200+
}
81978201
if (propTypes.length) {
81988202
return getUnionType(propTypes, UnionReduction.Subtype);
81998203
}
@@ -14615,7 +14619,7 @@ namespace ts {
1461514619
* with no call or construct signatures.
1461614620
*/
1461714621
function isObjectTypeWithInferableIndex(type: Type) {
14618-
return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.ValueModule)) !== 0 &&
14622+
return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.Enum | SymbolFlags.ValueModule)) !== 0 &&
1461914623
!typeHasCallOrConstructSignatures(type);
1462014624
}
1462114625

tests/baselines/reference/implicitIndexSignatures.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ function f4() {
4444
const v3 = getNumberIndexValue(o1);
4545
const v4 = getNumberIndexValue(o2);
4646
}
47+
48+
function f5() {
49+
enum E1 { A, B }
50+
enum E2 { A = "A", B = "B" }
51+
enum E3 { A = 0, B = "B" }
52+
const v1 = getStringIndexValue(E1);
53+
const v2 = getStringIndexValue(E2);
54+
const v3 = getStringIndexValue(E3);
55+
const v4 = getNumberIndexValue(E1);
56+
const v5 = getNumberIndexValue(E2);
57+
const v6 = getNumberIndexValue(E3);
58+
}
4759

4860

4961
//// [implicitIndexSignatures.js]
@@ -83,3 +95,26 @@ function f4() {
8395
var v3 = getNumberIndexValue(o1);
8496
var v4 = getNumberIndexValue(o2);
8597
}
98+
function f5() {
99+
var E1;
100+
(function (E1) {
101+
E1[E1["A"] = 0] = "A";
102+
E1[E1["B"] = 1] = "B";
103+
})(E1 || (E1 = {}));
104+
var E2;
105+
(function (E2) {
106+
E2["A"] = "A";
107+
E2["B"] = "B";
108+
})(E2 || (E2 = {}));
109+
var E3;
110+
(function (E3) {
111+
E3[E3["A"] = 0] = "A";
112+
E3["B"] = "B";
113+
})(E3 || (E3 = {}));
114+
var v1 = getStringIndexValue(E1);
115+
var v2 = getStringIndexValue(E2);
116+
var v3 = getStringIndexValue(E3);
117+
var v4 = getNumberIndexValue(E1);
118+
var v5 = getNumberIndexValue(E2);
119+
var v6 = getNumberIndexValue(E3);
120+
}

tests/baselines/reference/implicitIndexSignatures.symbols

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,52 @@ function f4() {
168168
>o2 : Symbol(o2, Decl(implicitIndexSignatures.ts, 39, 7))
169169
}
170170

171+
function f5() {
172+
>f5 : Symbol(f5, Decl(implicitIndexSignatures.ts, 44, 1))
173+
174+
enum E1 { A, B }
175+
>E1 : Symbol(E1, Decl(implicitIndexSignatures.ts, 46, 15))
176+
>A : Symbol(E1.A, Decl(implicitIndexSignatures.ts, 47, 13))
177+
>B : Symbol(E1.B, Decl(implicitIndexSignatures.ts, 47, 16))
178+
179+
enum E2 { A = "A", B = "B" }
180+
>E2 : Symbol(E2, Decl(implicitIndexSignatures.ts, 47, 20))
181+
>A : Symbol(E2.A, Decl(implicitIndexSignatures.ts, 48, 13))
182+
>B : Symbol(E2.B, Decl(implicitIndexSignatures.ts, 48, 22))
183+
184+
enum E3 { A = 0, B = "B" }
185+
>E3 : Symbol(E3, Decl(implicitIndexSignatures.ts, 48, 32))
186+
>A : Symbol(E3.A, Decl(implicitIndexSignatures.ts, 49, 13))
187+
>B : Symbol(E3.B, Decl(implicitIndexSignatures.ts, 49, 20))
188+
189+
const v1 = getStringIndexValue(E1);
190+
>v1 : Symbol(v1, Decl(implicitIndexSignatures.ts, 50, 9))
191+
>getStringIndexValue : Symbol(getStringIndexValue, Decl(implicitIndexSignatures.ts, 11, 13))
192+
>E1 : Symbol(E1, Decl(implicitIndexSignatures.ts, 46, 15))
193+
194+
const v2 = getStringIndexValue(E2);
195+
>v2 : Symbol(v2, Decl(implicitIndexSignatures.ts, 51, 9))
196+
>getStringIndexValue : Symbol(getStringIndexValue, Decl(implicitIndexSignatures.ts, 11, 13))
197+
>E2 : Symbol(E2, Decl(implicitIndexSignatures.ts, 47, 20))
198+
199+
const v3 = getStringIndexValue(E3);
200+
>v3 : Symbol(v3, Decl(implicitIndexSignatures.ts, 52, 9))
201+
>getStringIndexValue : Symbol(getStringIndexValue, Decl(implicitIndexSignatures.ts, 11, 13))
202+
>E3 : Symbol(E3, Decl(implicitIndexSignatures.ts, 48, 32))
203+
204+
const v4 = getNumberIndexValue(E1);
205+
>v4 : Symbol(v4, Decl(implicitIndexSignatures.ts, 53, 9))
206+
>getNumberIndexValue : Symbol(getNumberIndexValue, Decl(implicitIndexSignatures.ts, 13, 68))
207+
>E1 : Symbol(E1, Decl(implicitIndexSignatures.ts, 46, 15))
208+
209+
const v5 = getNumberIndexValue(E2);
210+
>v5 : Symbol(v5, Decl(implicitIndexSignatures.ts, 54, 9))
211+
>getNumberIndexValue : Symbol(getNumberIndexValue, Decl(implicitIndexSignatures.ts, 13, 68))
212+
>E2 : Symbol(E2, Decl(implicitIndexSignatures.ts, 47, 20))
213+
214+
const v6 = getNumberIndexValue(E3);
215+
>v6 : Symbol(v6, Decl(implicitIndexSignatures.ts, 55, 9))
216+
>getNumberIndexValue : Symbol(getNumberIndexValue, Decl(implicitIndexSignatures.ts, 13, 68))
217+
>E3 : Symbol(E3, Decl(implicitIndexSignatures.ts, 48, 32))
218+
}
219+

tests/baselines/reference/implicitIndexSignatures.types

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,62 @@ function f4() {
196196
>o2 : { 0: string; 1: string; count: number; }
197197
}
198198

199+
function f5() {
200+
>f5 : () => void
201+
202+
enum E1 { A, B }
203+
>E1 : E1
204+
>A : E1.A
205+
>B : E1.B
206+
207+
enum E2 { A = "A", B = "B" }
208+
>E2 : E2
209+
>A : E2.A
210+
>"A" : "A"
211+
>B : E2.B
212+
>"B" : "B"
213+
214+
enum E3 { A = 0, B = "B" }
215+
>E3 : E3
216+
>A : E3.A
217+
>0 : 0
218+
>B : E3.B
219+
>"B" : "B"
220+
221+
const v1 = getStringIndexValue(E1);
222+
>v1 : string | E1
223+
>getStringIndexValue(E1) : string | E1
224+
>getStringIndexValue : <T>(map: { [x: string]: T; }) => T
225+
>E1 : typeof E1
226+
227+
const v2 = getStringIndexValue(E2);
228+
>v2 : E2
229+
>getStringIndexValue(E2) : E2
230+
>getStringIndexValue : <T>(map: { [x: string]: T; }) => T
231+
>E2 : typeof E2
232+
233+
const v3 = getStringIndexValue(E3);
234+
>v3 : string | E3.A
235+
>getStringIndexValue(E3) : string | E3.A
236+
>getStringIndexValue : <T>(map: { [x: string]: T; }) => T
237+
>E3 : typeof E3
238+
239+
const v4 = getNumberIndexValue(E1);
240+
>v4 : string
241+
>getNumberIndexValue(E1) : string
242+
>getNumberIndexValue : <T>(map: { [x: number]: T; }) => T
243+
>E1 : typeof E1
244+
245+
const v5 = getNumberIndexValue(E2);
246+
>v5 : unknown
247+
>getNumberIndexValue(E2) : unknown
248+
>getNumberIndexValue : <T>(map: { [x: number]: T; }) => T
249+
>E2 : typeof E2
250+
251+
const v6 = getNumberIndexValue(E3);
252+
>v6 : string
253+
>getNumberIndexValue(E3) : string
254+
>getNumberIndexValue : <T>(map: { [x: number]: T; }) => T
255+
>E3 : typeof E3
256+
}
257+

tests/baselines/reference/useObjectValuesAndEntries1.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,16 +121,16 @@ enum E { A, B }
121121
>B : E.B
122122

123123
var entries5 = Object.entries(E); // [string, any][]
124-
>entries5 : [string, any][]
125-
>Object.entries(E) : [string, any][]
124+
>entries5 : [string, string | E][]
125+
>Object.entries(E) : [string, string | E][]
126126
>Object.entries : { <T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][]; (o: {}): [string, any][]; }
127127
>Object : ObjectConstructor
128128
>entries : { <T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][]; (o: {}): [string, any][]; }
129129
>E : typeof E
130130

131131
var values5 = Object.values(E); // any[]
132-
>values5 : any[]
133-
>Object.values(E) : any[]
132+
>values5 : (string | E)[]
133+
>Object.values(E) : (string | E)[]
134134
>Object.values : { <T>(o: { [s: string]: T; } | ArrayLike<T>): T[]; (o: {}): any[]; }
135135
>Object : ObjectConstructor
136136
>values : { <T>(o: { [s: string]: T; } | ArrayLike<T>): T[]; (o: {}): any[]; }

tests/cases/compiler/implicitIndexSignatures.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,15 @@ function f4() {
4343
const v3 = getNumberIndexValue(o1);
4444
const v4 = getNumberIndexValue(o2);
4545
}
46+
47+
function f5() {
48+
enum E1 { A, B }
49+
enum E2 { A = "A", B = "B" }
50+
enum E3 { A = 0, B = "B" }
51+
const v1 = getStringIndexValue(E1);
52+
const v2 = getStringIndexValue(E2);
53+
const v3 = getStringIndexValue(E3);
54+
const v4 = getNumberIndexValue(E1);
55+
const v5 = getNumberIndexValue(E2);
56+
const v6 = getNumberIndexValue(E3);
57+
}

0 commit comments

Comments
 (0)