Skip to content

Commit b93da62

Browse files
authored
Emit non-identifier enum member references as typeof parent[some name] (microsoft#40679)
1 parent 798b18b commit b93da62

27 files changed

+143
-43
lines changed

src/compiler/checker.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4403,13 +4403,26 @@ namespace ts {
44034403
if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) {
44044404
const parentSymbol = getParentOfSymbol(type.symbol)!;
44054405
const parentName = symbolToTypeNode(parentSymbol, context, SymbolFlags.Type);
4406-
const enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type
4407-
? parentName
4408-
: appendReferenceToType(
4406+
if (getDeclaredTypeOfSymbol(parentSymbol) === type) {
4407+
return parentName;
4408+
}
4409+
const memberName = symbolName(type.symbol);
4410+
if (isIdentifierText(memberName, ScriptTarget.ES3)) {
4411+
return appendReferenceToType(
44094412
parentName as TypeReferenceNode | ImportTypeNode,
4410-
factory.createTypeReferenceNode(symbolName(type.symbol), /*typeArguments*/ undefined)
4413+
factory.createTypeReferenceNode(memberName, /*typeArguments*/ undefined)
44114414
);
4412-
return enumLiteralName;
4415+
}
4416+
if (isImportTypeNode(parentName)) {
4417+
(parentName as any).isTypeOf = true; // mutably update, node is freshly manufactured anyhow
4418+
return factory.createIndexedAccessTypeNode(parentName, factory.createLiteralTypeNode(factory.createStringLiteral(memberName)));
4419+
}
4420+
else if (isTypeReferenceNode(parentName)) {
4421+
return factory.createIndexedAccessTypeNode(factory.createTypeQueryNode(parentName.typeName), factory.createLiteralTypeNode(factory.createStringLiteral(memberName)));
4422+
}
4423+
else {
4424+
return Debug.fail("Unhandled type node kind returned from `symbolToTypeNode`.");
4425+
}
44134426
}
44144427
if (type.flags & TypeFlags.EnumLike) {
44154428
return symbolToTypeNode(type.symbol, context, SymbolFlags.Type);

tests/baselines/reference/ambientConstLiterals.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ enum E { A, B, C, "non identifier" }
1212
>A : E.A
1313
>B : E.B
1414
>C : E.C
15-
>"non identifier" : E.non identifier
15+
>"non identifier" : typeof E["non identifier"]
1616

1717
const c1 = "abc";
1818
>c1 : "abc"
@@ -54,8 +54,8 @@ const c8 = E.A;
5454
>A : E.A
5555

5656
const c8b = E["non identifier"];
57-
>c8b : E.non identifier
58-
>E["non identifier"] : E.non identifier
57+
>c8b : typeof E["non identifier"]
58+
>E["non identifier"] : typeof E["non identifier"]
5959
>E : typeof E
6060
>"non identifier" : "non identifier"
6161

tests/baselines/reference/bitwiseNotOperatorWithEnumType.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ enum ENUM1 { A, B, "" };
55
>ENUM1 : ENUM1
66
>A : ENUM1.A
77
>B : ENUM1.B
8-
>"" : ENUM1.
8+
>"" : typeof ENUM1[""]
99

1010
// enum type var
1111
var ResultIsNumber1 = ~ENUM1;

tests/baselines/reference/declFileEnums.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ enum e5 {
8383
>"Sunday" : e5.Sunday
8484

8585
"Weekend days"
86-
>"Weekend days" : e5.Weekend days
86+
>"Weekend days" : typeof e5["Weekend days"]
8787
}
8888

8989

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//// [declarationEmitSpreadStringlyKeyedEnum.ts]
2+
enum AgeGroups { "0-17" , "18-22" , "23-27" , "28-34" , "35-44" , "45-59" , "60-150" }
3+
export const SpotifyAgeGroupEnum = { ...AgeGroups };
4+
5+
//// [declarationEmitSpreadStringlyKeyedEnum.js]
6+
"use strict";
7+
var __assign = (this && this.__assign) || function () {
8+
__assign = Object.assign || function(t) {
9+
for (var s, i = 1, n = arguments.length; i < n; i++) {
10+
s = arguments[i];
11+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
12+
t[p] = s[p];
13+
}
14+
return t;
15+
};
16+
return __assign.apply(this, arguments);
17+
};
18+
exports.__esModule = true;
19+
exports.SpotifyAgeGroupEnum = void 0;
20+
var AgeGroups;
21+
(function (AgeGroups) {
22+
AgeGroups[AgeGroups["0-17"] = 0] = "0-17";
23+
AgeGroups[AgeGroups["18-22"] = 1] = "18-22";
24+
AgeGroups[AgeGroups["23-27"] = 2] = "23-27";
25+
AgeGroups[AgeGroups["28-34"] = 3] = "28-34";
26+
AgeGroups[AgeGroups["35-44"] = 4] = "35-44";
27+
AgeGroups[AgeGroups["45-59"] = 5] = "45-59";
28+
AgeGroups[AgeGroups["60-150"] = 6] = "60-150";
29+
})(AgeGroups || (AgeGroups = {}));
30+
exports.SpotifyAgeGroupEnum = __assign({}, AgeGroups);
31+
32+
33+
//// [declarationEmitSpreadStringlyKeyedEnum.d.ts]
34+
declare enum AgeGroups {
35+
"0-17" = 0,
36+
"18-22" = 1,
37+
"23-27" = 2,
38+
"28-34" = 3,
39+
"35-44" = 4,
40+
"45-59" = 5,
41+
"60-150" = 6
42+
}
43+
export declare const SpotifyAgeGroupEnum: {
44+
[x: number]: string;
45+
"0-17": typeof AgeGroups["0-17"];
46+
"18-22": typeof AgeGroups["18-22"];
47+
"23-27": typeof AgeGroups["23-27"];
48+
"28-34": typeof AgeGroups["28-34"];
49+
"35-44": typeof AgeGroups["35-44"];
50+
"45-59": typeof AgeGroups["45-59"];
51+
"60-150": typeof AgeGroups["60-150"];
52+
};
53+
export {};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
=== tests/cases/compiler/declarationEmitSpreadStringlyKeyedEnum.ts ===
2+
enum AgeGroups { "0-17" , "18-22" , "23-27" , "28-34" , "35-44" , "45-59" , "60-150" }
3+
>AgeGroups : Symbol(AgeGroups, Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 0))
4+
>"0-17" : Symbol(AgeGroups["0-17"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 16))
5+
>"18-22" : Symbol(AgeGroups["18-22"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 25))
6+
>"23-27" : Symbol(AgeGroups["23-27"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 35))
7+
>"28-34" : Symbol(AgeGroups["28-34"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 45))
8+
>"35-44" : Symbol(AgeGroups["35-44"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 55))
9+
>"45-59" : Symbol(AgeGroups["45-59"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 65))
10+
>"60-150" : Symbol(AgeGroups["60-150"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 75))
11+
12+
export const SpotifyAgeGroupEnum = { ...AgeGroups };
13+
>SpotifyAgeGroupEnum : Symbol(SpotifyAgeGroupEnum, Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 1, 12))
14+
>AgeGroups : Symbol(AgeGroups, Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 0))
15+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/compiler/declarationEmitSpreadStringlyKeyedEnum.ts ===
2+
enum AgeGroups { "0-17" , "18-22" , "23-27" , "28-34" , "35-44" , "45-59" , "60-150" }
3+
>AgeGroups : AgeGroups
4+
>"0-17" : typeof AgeGroups["0-17"]
5+
>"18-22" : typeof AgeGroups["18-22"]
6+
>"23-27" : typeof AgeGroups["23-27"]
7+
>"28-34" : typeof AgeGroups["28-34"]
8+
>"35-44" : typeof AgeGroups["35-44"]
9+
>"45-59" : typeof AgeGroups["45-59"]
10+
>"60-150" : typeof AgeGroups["60-150"]
11+
12+
export const SpotifyAgeGroupEnum = { ...AgeGroups };
13+
>SpotifyAgeGroupEnum : { [x: number]: string; "0-17": typeof AgeGroups["0-17"]; "18-22": typeof AgeGroups["18-22"]; "23-27": typeof AgeGroups["23-27"]; "28-34": typeof AgeGroups["28-34"]; "35-44": typeof AgeGroups["35-44"]; "45-59": typeof AgeGroups["45-59"]; "60-150": typeof AgeGroups["60-150"]; }
14+
>{ ...AgeGroups } : { [x: number]: string; "0-17": typeof AgeGroups["0-17"]; "18-22": typeof AgeGroups["18-22"]; "23-27": typeof AgeGroups["23-27"]; "28-34": typeof AgeGroups["28-34"]; "35-44": typeof AgeGroups["35-44"]; "45-59": typeof AgeGroups["45-59"]; "60-150": typeof AgeGroups["60-150"]; }
15+
>AgeGroups : typeof AgeGroups
16+

tests/baselines/reference/decrementOperatorWithEnumType.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ enum ENUM1 { A, B, "" };
55
>ENUM1 : ENUM1
66
>A : ENUM1.A
77
>B : ENUM1.B
8-
>"" : ENUM1.
8+
>"" : typeof ENUM1[""]
99

1010
// expression
1111
var ResultIsNumber1 = --ENUM1["A"];

tests/baselines/reference/decrementOperatorWithEnumTypeInvalidOperations.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ enum ENUM1 { A, B, "" };
88
>ENUM1 : ENUM1
99
>A : ENUM1.A
1010
>B : ENUM1.B
11-
>"" : ENUM1.
11+
>"" : typeof ENUM1[""]
1212

1313
// enum type var
1414
var ResultIsNumber1 = --ENUM;

tests/baselines/reference/deleteOperatorWithEnumType.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ enum ENUM1 { A, B, "" };
88
>ENUM1 : ENUM1
99
>A : ENUM1.A
1010
>B : ENUM1.B
11-
>"" : ENUM1.
11+
>"" : typeof ENUM1[""]
1212

1313
// enum type var
1414
var ResultIsBoolean1 = delete ENUM;

0 commit comments

Comments
 (0)