Emit non-identifier enum member references as typeof parent[some name] (#40679)

This commit is contained in:
Wesley Wigham
2020-10-01 13:06:17 -07:00
committed by GitHub
parent 798b18be6e
commit b93da6291a
27 changed files with 143 additions and 43 deletions

View File

@@ -4403,13 +4403,26 @@ namespace ts {
if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) {
const parentSymbol = getParentOfSymbol(type.symbol)!;
const parentName = symbolToTypeNode(parentSymbol, context, SymbolFlags.Type);
const enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type
? parentName
: appendReferenceToType(
if (getDeclaredTypeOfSymbol(parentSymbol) === type) {
return parentName;
}
const memberName = symbolName(type.symbol);
if (isIdentifierText(memberName, ScriptTarget.ES3)) {
return appendReferenceToType(
parentName as TypeReferenceNode | ImportTypeNode,
factory.createTypeReferenceNode(symbolName(type.symbol), /*typeArguments*/ undefined)
factory.createTypeReferenceNode(memberName, /*typeArguments*/ undefined)
);
return enumLiteralName;
}
if (isImportTypeNode(parentName)) {
(parentName as any).isTypeOf = true; // mutably update, node is freshly manufactured anyhow
return factory.createIndexedAccessTypeNode(parentName, factory.createLiteralTypeNode(factory.createStringLiteral(memberName)));
}
else if (isTypeReferenceNode(parentName)) {
return factory.createIndexedAccessTypeNode(factory.createTypeQueryNode(parentName.typeName), factory.createLiteralTypeNode(factory.createStringLiteral(memberName)));
}
else {
return Debug.fail("Unhandled type node kind returned from `symbolToTypeNode`.");
}
}
if (type.flags & TypeFlags.EnumLike) {
return symbolToTypeNode(type.symbol, context, SymbolFlags.Type);

View File

@@ -12,7 +12,7 @@ enum E { A, B, C, "non identifier" }
>A : E.A
>B : E.B
>C : E.C
>"non identifier" : E.non identifier
>"non identifier" : typeof E["non identifier"]
const c1 = "abc";
>c1 : "abc"
@@ -54,8 +54,8 @@ const c8 = E.A;
>A : E.A
const c8b = E["non identifier"];
>c8b : E.non identifier
>E["non identifier"] : E.non identifier
>c8b : typeof E["non identifier"]
>E["non identifier"] : typeof E["non identifier"]
>E : typeof E
>"non identifier" : "non identifier"

View File

@@ -5,7 +5,7 @@ enum ENUM1 { A, B, "" };
>ENUM1 : ENUM1
>A : ENUM1.A
>B : ENUM1.B
>"" : ENUM1.
>"" : typeof ENUM1[""]
// enum type var
var ResultIsNumber1 = ~ENUM1;

View File

@@ -83,7 +83,7 @@ enum e5 {
>"Sunday" : e5.Sunday
"Weekend days"
>"Weekend days" : e5.Weekend days
>"Weekend days" : typeof e5["Weekend days"]
}

View File

@@ -0,0 +1,53 @@
//// [declarationEmitSpreadStringlyKeyedEnum.ts]
enum AgeGroups { "0-17" , "18-22" , "23-27" , "28-34" , "35-44" , "45-59" , "60-150" }
export const SpotifyAgeGroupEnum = { ...AgeGroups };
//// [declarationEmitSpreadStringlyKeyedEnum.js]
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
exports.__esModule = true;
exports.SpotifyAgeGroupEnum = void 0;
var AgeGroups;
(function (AgeGroups) {
AgeGroups[AgeGroups["0-17"] = 0] = "0-17";
AgeGroups[AgeGroups["18-22"] = 1] = "18-22";
AgeGroups[AgeGroups["23-27"] = 2] = "23-27";
AgeGroups[AgeGroups["28-34"] = 3] = "28-34";
AgeGroups[AgeGroups["35-44"] = 4] = "35-44";
AgeGroups[AgeGroups["45-59"] = 5] = "45-59";
AgeGroups[AgeGroups["60-150"] = 6] = "60-150";
})(AgeGroups || (AgeGroups = {}));
exports.SpotifyAgeGroupEnum = __assign({}, AgeGroups);
//// [declarationEmitSpreadStringlyKeyedEnum.d.ts]
declare enum AgeGroups {
"0-17" = 0,
"18-22" = 1,
"23-27" = 2,
"28-34" = 3,
"35-44" = 4,
"45-59" = 5,
"60-150" = 6
}
export declare const 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"];
};
export {};

View File

@@ -0,0 +1,15 @@
=== tests/cases/compiler/declarationEmitSpreadStringlyKeyedEnum.ts ===
enum AgeGroups { "0-17" , "18-22" , "23-27" , "28-34" , "35-44" , "45-59" , "60-150" }
>AgeGroups : Symbol(AgeGroups, Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 0))
>"0-17" : Symbol(AgeGroups["0-17"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 16))
>"18-22" : Symbol(AgeGroups["18-22"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 25))
>"23-27" : Symbol(AgeGroups["23-27"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 35))
>"28-34" : Symbol(AgeGroups["28-34"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 45))
>"35-44" : Symbol(AgeGroups["35-44"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 55))
>"45-59" : Symbol(AgeGroups["45-59"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 65))
>"60-150" : Symbol(AgeGroups["60-150"], Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 75))
export const SpotifyAgeGroupEnum = { ...AgeGroups };
>SpotifyAgeGroupEnum : Symbol(SpotifyAgeGroupEnum, Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 1, 12))
>AgeGroups : Symbol(AgeGroups, Decl(declarationEmitSpreadStringlyKeyedEnum.ts, 0, 0))

View File

@@ -0,0 +1,16 @@
=== tests/cases/compiler/declarationEmitSpreadStringlyKeyedEnum.ts ===
enum AgeGroups { "0-17" , "18-22" , "23-27" , "28-34" , "35-44" , "45-59" , "60-150" }
>AgeGroups : AgeGroups
>"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"]
export const SpotifyAgeGroupEnum = { ...AgeGroups };
>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"]; }
>{ ...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"]; }
>AgeGroups : typeof AgeGroups

View File

@@ -5,7 +5,7 @@ enum ENUM1 { A, B, "" };
>ENUM1 : ENUM1
>A : ENUM1.A
>B : ENUM1.B
>"" : ENUM1.
>"" : typeof ENUM1[""]
// expression
var ResultIsNumber1 = --ENUM1["A"];

View File

@@ -8,7 +8,7 @@ enum ENUM1 { A, B, "" };
>ENUM1 : ENUM1
>A : ENUM1.A
>B : ENUM1.B
>"" : ENUM1.
>"" : typeof ENUM1[""]
// enum type var
var ResultIsNumber1 = --ENUM;

View File

@@ -8,7 +8,7 @@ enum ENUM1 { A, B, "" };
>ENUM1 : ENUM1
>A : ENUM1.A
>B : ENUM1.B
>"" : ENUM1.
>"" : typeof ENUM1[""]
// enum type var
var ResultIsBoolean1 = delete ENUM;

View File

@@ -7,11 +7,11 @@ enum Foo {
>1 : 1
"(Anonymous function)" = 2,
>"(Anonymous function)" : Foo.(Anonymous function)
>"(Anonymous function)" : typeof Foo["(Anonymous function)"]
>2 : 2
"(Anonymous class)" = 4,
>"(Anonymous class)" : Foo.(Anonymous class)
>"(Anonymous class)" : typeof Foo["(Anonymous class)"]
>4 : 4
"__call" = 10

View File

@@ -132,11 +132,11 @@ enum E13 {
postColonValueComma: 2,
>postColonValueComma : E13.postColonValueComma
>2 : E13.2
>2 : typeof E13["2"]
postColonValueSemicolon: 3;
>postColonValueSemicolon : E13.postColonValueSemicolon
>3 : E13.3
>3 : typeof E13["3"]
};
@@ -146,7 +146,7 @@ enum E14 { a, b: any "hello" += 1, c, d}
>b : E14.b
>any : E14.any
>"hello" : E14.hello
>1 : E14.1
>1 : typeof E14["1"]
>c : E14.c
>d : E14.d

View File

@@ -3,17 +3,17 @@ enum Nums {
>Nums : Nums
1.0,
>1.0 : Nums.1
>1.0 : typeof Nums["1"]
11e-1,
>11e-1 : Nums.1.1
>11e-1 : typeof Nums["1.1"]
0.12e1,
>0.12e1 : Nums.1.2
>0.12e1 : typeof Nums["1.2"]
"13e-1",
>"13e-1" : Nums.13e-1
>"13e-1" : typeof Nums["13e-1"]
0xF00D
>0xF00D : Nums.61453
>0xF00D : typeof Nums["61453"]
}

View File

@@ -3,7 +3,7 @@ enum A {
>A : A
"-Infinity" = 1
>"-Infinity" : A.-Infinity
>"-Infinity" : typeof A["-Infinity"]
>1 : 1
}

View File

@@ -3,5 +3,5 @@ enum E {
>E : E
'fo"o',
>'fo"o' : E.fo"o
>'fo"o' : typeof E["fo\"o"]
}

View File

@@ -3,5 +3,5 @@ enum E {
>E : E
"fo'o",
>"fo'o" : E.fo'o
>"fo'o" : typeof E["fo'o"]
}

View File

@@ -3,6 +3,6 @@ enum E {
>E : E
'gold \u2730'
>'gold \u2730' : E.gold ✰
>'gold \u2730' : typeof E["gold \u2730"]
}

View File

@@ -5,7 +5,7 @@ enum ENUM1 { A, B, "" };
>ENUM1 : ENUM1
>A : ENUM1.A
>B : ENUM1.B
>"" : ENUM1.
>"" : typeof ENUM1[""]
// expression
var ResultIsNumber1 = ++ENUM1["B"];

View File

@@ -8,7 +8,7 @@ enum ENUM1 { A, B, "" };
>ENUM1 : ENUM1
>A : ENUM1.A
>B : ENUM1.B
>"" : ENUM1.
>"" : typeof ENUM1[""]
// enum type var
var ResultIsNumber1 = ++ENUM;

View File

@@ -161,20 +161,20 @@ enum X {
>X : X
1 = 1,
>1 : X.1
>1 : typeof X["1"]
>1 : 1
[2] = 2,
>[2] : X.2
>[2] : typeof X["2"]
>2 : 2
>2 : 2
"3" = 3,
>"3" : X.3
>"3" : typeof X["3"]
>3 : 3
["4"] = 4,
>["4"] : X.4
>["4"] : typeof X["4"]
>"4" : "4"
>4 : 4

View File

@@ -8,7 +8,7 @@ enum ENUM1 { A, B, "" };
>ENUM1 : ENUM1
>A : ENUM1.A
>B : ENUM1.B
>"" : ENUM1.
>"" : typeof ENUM1[""]
// enum type var
var ResultIsNumber1 = -ENUM;
@@ -32,7 +32,7 @@ var ResultIsNumber3 = -(ENUM1.B + ENUM1[""]);
>ENUM1.B : ENUM1.B
>ENUM1 : typeof ENUM1
>B : ENUM1.B
>ENUM1[""] : ENUM1.
>ENUM1[""] : typeof ENUM1[""]
>ENUM1 : typeof ENUM1
>"" : ""

View File

@@ -6,13 +6,13 @@ enum E2 { a, }
enum E3 { a: 1, }
>E3 : E3
>a : E3.a
>1 : E3.1
>1 : typeof E3["1"]
enum E1 { a, b: 1, c, d: 2 = 3 }
>E1 : E1
>a : E1.a
>b : E1.b
>1 : E1.1
>1 : typeof E1["1"]
>c : E1.c
>d : E1.d
>2 : E1.c

View File

@@ -3,7 +3,7 @@ enum E {
>E : E
1, 2, 3
>1 : E.1
>2 : E.2
>3 : E.3
>1 : typeof E["1"]
>2 : typeof E["2"]
>3 : typeof E["3"]
}

View File

@@ -8,7 +8,7 @@ enum ENUM1 { A, B, "" };
>ENUM1 : ENUM1
>A : ENUM1.A
>B : ENUM1.B
>"" : ENUM1.
>"" : typeof ENUM1[""]
// enum type var
var ResultIsNumber1 = +ENUM;

View File

@@ -8,7 +8,7 @@ enum ENUM1 { A, B, "" };
>ENUM1 : ENUM1
>A : ENUM1.A
>B : ENUM1.B
>"" : ENUM1.
>"" : typeof ENUM1[""]
// enum type var
var ResultIsString1 = typeof ENUM;

View File

@@ -8,7 +8,7 @@ enum ENUM1 { A, B, "" };
>ENUM1 : ENUM1
>A : ENUM1.A
>B : ENUM1.B
>"" : ENUM1.
>"" : typeof ENUM1[""]
// enum type var
var ResultIsAny1 = void ENUM;

View File

@@ -0,0 +1,3 @@
// @declaration: true
enum AgeGroups { "0-17" , "18-22" , "23-27" , "28-34" , "35-44" , "45-59" , "60-150" }
export const SpotifyAgeGroupEnum = { ...AgeGroups };