Skip to content

Commit 82fc9b1

Browse files
authored
fix(43154): emit typeof type for static methods with a computed name (microsoft#46923)
1 parent d12020d commit 82fc9b1

5 files changed

+460
-2
lines changed

src/compiler/checker.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -6154,8 +6154,8 @@ namespace ts {
61546154
function createAccessFromSymbolChain(chain: Symbol[], index: number, stopper: number): EntityName | IndexedAccessTypeNode {
61556155
const typeParameterNodes = index === (chain.length - 1) ? overrideTypeArguments : lookupTypeParameterNodes(chain, index, context);
61566156
const symbol = chain[index];
6157-
61586157
const parent = chain[index - 1];
6158+
61596159
let symbolName: string | undefined;
61606160
if (index === 0) {
61616161
context.flags |= NodeBuilderFlags.InInitialEntityName;
@@ -6174,7 +6174,16 @@ namespace ts {
61746174
});
61756175
}
61766176
}
6177-
if (!symbolName) {
6177+
6178+
if (symbolName === undefined) {
6179+
const name = firstDefined(symbol.declarations, getNameOfDeclaration);
6180+
if (name && isComputedPropertyName(name) && isEntityName(name.expression)) {
6181+
const LHS = createAccessFromSymbolChain(chain, index - 1, stopper);
6182+
if (isEntityName(LHS)) {
6183+
return factory.createIndexedAccessTypeNode(factory.createParenthesizedType(factory.createTypeQueryNode(LHS)), factory.createTypeQueryNode(name.expression));
6184+
}
6185+
return LHS;
6186+
}
61786187
symbolName = getNameOfSymbolAsWritten(symbol, context);
61796188
}
61806189
context.approximateLength += symbolName.length + 1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//// [declarationEmitClassMemberWithComputedPropertyName.ts]
2+
const k1 = Symbol();
3+
const k2 = 'foo' as const;
4+
5+
const k3 = Symbol();
6+
const k4 = 'prop' as const;
7+
8+
class Foo {
9+
static [k1](): number {
10+
return 1;
11+
}
12+
[k1](): string {
13+
return "";
14+
}
15+
16+
static [k2]() {
17+
return 1;
18+
}
19+
[k2]() {
20+
return "";
21+
}
22+
23+
static m1() {}
24+
m1() {}
25+
26+
static [k3] = 1;
27+
[k3] = 1;
28+
29+
static [k4] = 1;
30+
[k4] = 2;
31+
32+
static p1 = 3;
33+
p1 = 4;
34+
}
35+
36+
export const t1 = Foo[k1];
37+
export const t2 = new Foo()[k1];
38+
39+
export const t3 = Foo[k2];
40+
export const t4 = new Foo()[k2];
41+
42+
export const t5 = Foo.m1;
43+
export const t6 = new Foo().m1;
44+
45+
export const t7 = Foo[k3];
46+
export const t8 = new Foo()[k3];
47+
48+
export const t9 = Foo[k4];
49+
export const t10 = new Foo()[k4];
50+
51+
export const t11 = Foo.p1;
52+
export const t12 = new Foo().p1;
53+
54+
55+
56+
57+
//// [declarationEmitClassMemberWithComputedPropertyName.d.ts]
58+
declare const k1: unique symbol;
59+
declare const k2: "foo";
60+
declare const k3: unique symbol;
61+
declare const k4: "prop";
62+
declare class Foo {
63+
static [k1](): number;
64+
[k1](): string;
65+
static [k2](): number;
66+
[k2](): string;
67+
static m1(): void;
68+
m1(): void;
69+
static [k3]: number;
70+
[k3]: number;
71+
static [k4]: number;
72+
[k4]: number;
73+
static p1: number;
74+
p1: number;
75+
}
76+
export declare const t1: (typeof Foo)[typeof k1];
77+
export declare const t2: () => string;
78+
export declare const t3: typeof Foo.foo;
79+
export declare const t4: () => string;
80+
export declare const t5: typeof Foo.m1;
81+
export declare const t6: () => void;
82+
export declare const t7: number;
83+
export declare const t8: number;
84+
export declare const t9: number;
85+
export declare const t10: number;
86+
export declare const t11: number;
87+
export declare const t12: number;
88+
export {};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
=== tests/cases/compiler/declarationEmitClassMemberWithComputedPropertyName.ts ===
2+
const k1 = Symbol();
3+
>k1 : Symbol(k1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 0, 5))
4+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
5+
6+
const k2 = 'foo' as const;
7+
>k2 : Symbol(k2, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 1, 5))
8+
>const : Symbol(const)
9+
10+
const k3 = Symbol();
11+
>k3 : Symbol(k3, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 3, 5))
12+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
13+
14+
const k4 = 'prop' as const;
15+
>k4 : Symbol(k4, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 5))
16+
>const : Symbol(const)
17+
18+
class Foo {
19+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
20+
21+
static [k1](): number {
22+
>[k1] : Symbol(Foo[k1], Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 6, 11))
23+
>k1 : Symbol(k1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 0, 5))
24+
25+
return 1;
26+
}
27+
[k1](): string {
28+
>[k1] : Symbol(Foo[k1], Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 9, 5))
29+
>k1 : Symbol(k1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 0, 5))
30+
31+
return "";
32+
}
33+
34+
static [k2]() {
35+
>[k2] : Symbol(Foo[k2], Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 12, 5))
36+
>k2 : Symbol(k2, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 1, 5))
37+
38+
return 1;
39+
}
40+
[k2]() {
41+
>[k2] : Symbol(Foo[k2], Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 16, 5))
42+
>k2 : Symbol(k2, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 1, 5))
43+
44+
return "";
45+
}
46+
47+
static m1() {}
48+
>m1 : Symbol(Foo.m1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 19, 5))
49+
50+
m1() {}
51+
>m1 : Symbol(Foo.m1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 21, 18))
52+
53+
static [k3] = 1;
54+
>[k3] : Symbol(Foo[k3], Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 22, 11))
55+
>k3 : Symbol(k3, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 3, 5))
56+
57+
[k3] = 1;
58+
>[k3] : Symbol(Foo[k3], Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 24, 20))
59+
>k3 : Symbol(k3, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 3, 5))
60+
61+
static [k4] = 1;
62+
>[k4] : Symbol(Foo[k4], Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 25, 13))
63+
>k4 : Symbol(k4, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 5))
64+
65+
[k4] = 2;
66+
>[k4] : Symbol(Foo[k4], Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 27, 20))
67+
>k4 : Symbol(k4, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 5))
68+
69+
static p1 = 3;
70+
>p1 : Symbol(Foo.p1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 28, 13))
71+
72+
p1 = 4;
73+
>p1 : Symbol(Foo.p1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 30, 18))
74+
}
75+
76+
export const t1 = Foo[k1];
77+
>t1 : Symbol(t1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 34, 12))
78+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
79+
>k1 : Symbol(k1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 0, 5))
80+
81+
export const t2 = new Foo()[k1];
82+
>t2 : Symbol(t2, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 35, 12))
83+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
84+
>k1 : Symbol(k1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 0, 5))
85+
86+
export const t3 = Foo[k2];
87+
>t3 : Symbol(t3, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 37, 12))
88+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
89+
>k2 : Symbol(k2, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 1, 5))
90+
91+
export const t4 = new Foo()[k2];
92+
>t4 : Symbol(t4, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 38, 12))
93+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
94+
>k2 : Symbol(k2, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 1, 5))
95+
96+
export const t5 = Foo.m1;
97+
>t5 : Symbol(t5, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 40, 12))
98+
>Foo.m1 : Symbol(Foo.m1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 19, 5))
99+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
100+
>m1 : Symbol(Foo.m1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 19, 5))
101+
102+
export const t6 = new Foo().m1;
103+
>t6 : Symbol(t6, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 41, 12))
104+
>new Foo().m1 : Symbol(Foo.m1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 21, 18))
105+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
106+
>m1 : Symbol(Foo.m1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 21, 18))
107+
108+
export const t7 = Foo[k3];
109+
>t7 : Symbol(t7, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 43, 12))
110+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
111+
>k3 : Symbol(k3, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 3, 5))
112+
113+
export const t8 = new Foo()[k3];
114+
>t8 : Symbol(t8, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 44, 12))
115+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
116+
>k3 : Symbol(k3, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 3, 5))
117+
118+
export const t9 = Foo[k4];
119+
>t9 : Symbol(t9, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 46, 12))
120+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
121+
>k4 : Symbol(k4, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 5))
122+
123+
export const t10 = new Foo()[k4];
124+
>t10 : Symbol(t10, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 47, 12))
125+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
126+
>k4 : Symbol(k4, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 5))
127+
128+
export const t11 = Foo.p1;
129+
>t11 : Symbol(t11, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 49, 12))
130+
>Foo.p1 : Symbol(Foo.p1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 28, 13))
131+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
132+
>p1 : Symbol(Foo.p1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 28, 13))
133+
134+
export const t12 = new Foo().p1;
135+
>t12 : Symbol(t12, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 50, 12))
136+
>new Foo().p1 : Symbol(Foo.p1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 30, 18))
137+
>Foo : Symbol(Foo, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 4, 27))
138+
>p1 : Symbol(Foo.p1, Decl(declarationEmitClassMemberWithComputedPropertyName.ts, 30, 18))
139+

0 commit comments

Comments
 (0)