Skip to content

Commit c81bf4d

Browse files
authoredSep 26, 2022
fix(49594): Typescript 4.7.3 bracketed class property compilation error strictPropertyInitialization:true (#49619)
* fix(49594): allow enum members in computed properties * add additional tests * handle enum members without initializers * update tests
1 parent bc9cbbe commit c81bf4d

14 files changed

+306
-2
lines changed
 

‎src/compiler/checker.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -23665,7 +23665,7 @@ namespace ts {
2366523665
}
2366623666
if (isEntityNameExpression(node.argumentExpression)) {
2366723667
const symbol = resolveEntityName(node.argumentExpression, SymbolFlags.Value, /*ignoreErrors*/ true);
23668-
if (!symbol || !isConstVariable(symbol)) return undefined;
23668+
if (!symbol || !(isConstVariable(symbol) || (symbol.flags & SymbolFlags.EnumMember))) return undefined;
2366923669

2367023670
const declaration = symbol.valueDeclaration;
2367123671
if (declaration === undefined) return undefined;
@@ -23680,7 +23680,12 @@ namespace ts {
2368023680

2368123681
if (hasOnlyExpressionInitializer(declaration) && isBlockScopedNameDeclaredBeforeUse(declaration, node.argumentExpression)) {
2368223682
const initializer = getEffectiveInitializer(declaration);
23683-
return initializer && tryGetNameFromType(getTypeOfExpression(initializer));
23683+
if (initializer) {
23684+
return tryGetNameFromType(getTypeOfExpression(initializer));
23685+
}
23686+
if (isEnumMember(declaration)) {
23687+
return getTextOfPropertyName(declaration.name);
23688+
}
2368423689
}
2368523690
}
2368623691
return undefined;

‎tests/baselines/reference/strictPropertyInitialization.errors.txt

+11
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,15 @@ tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitial
179179
this['c'] = 1;
180180
}
181181
}
182+
183+
enum E {
184+
A = "A",
185+
B = "B"
186+
}
187+
class C13 {
188+
[E.A]: number;
189+
constructor() {
190+
this[E.A] = 1;
191+
}
192+
}
182193

‎tests/baselines/reference/strictPropertyInitialization.js

+30
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,17 @@ class C12 {
147147
this['c'] = 1;
148148
}
149149
}
150+
151+
enum E {
152+
A = "A",
153+
B = "B"
154+
}
155+
class C13 {
156+
[E.A]: number;
157+
constructor() {
158+
this[E.A] = 1;
159+
}
160+
}
150161

151162

152163
//// [strictPropertyInitialization.js]
@@ -259,6 +270,17 @@ class C12 {
259270
this['c'] = 1;
260271
}
261272
}
273+
var E;
274+
(function (E) {
275+
E["A"] = "A";
276+
E["B"] = "B";
277+
})(E || (E = {}));
278+
class C13 {
279+
constructor() {
280+
this[E.A] = 1;
281+
}
282+
}
283+
E.A;
262284

263285

264286
//// [strictPropertyInitialization.d.ts]
@@ -335,3 +357,11 @@ declare class C12 {
335357
['c']: number;
336358
constructor();
337359
}
360+
declare enum E {
361+
A = "A",
362+
B = "B"
363+
}
364+
declare class C13 {
365+
[E.A]: number;
366+
constructor();
367+
}

‎tests/baselines/reference/strictPropertyInitialization.symbols

+27
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,30 @@ class C12 {
348348
}
349349
}
350350

351+
enum E {
352+
>E : Symbol(E, Decl(strictPropertyInitialization.ts, 147, 1))
353+
354+
A = "A",
355+
>A : Symbol(E.A, Decl(strictPropertyInitialization.ts, 149, 8))
356+
357+
B = "B"
358+
>B : Symbol(E.B, Decl(strictPropertyInitialization.ts, 150, 12))
359+
}
360+
class C13 {
361+
>C13 : Symbol(C13, Decl(strictPropertyInitialization.ts, 152, 1))
362+
363+
[E.A]: number;
364+
>[E.A] : Symbol(C13[E.A], Decl(strictPropertyInitialization.ts, 153, 11))
365+
>E.A : Symbol(E.A, Decl(strictPropertyInitialization.ts, 149, 8))
366+
>E : Symbol(E, Decl(strictPropertyInitialization.ts, 147, 1))
367+
>A : Symbol(E.A, Decl(strictPropertyInitialization.ts, 149, 8))
368+
369+
constructor() {
370+
this[E.A] = 1;
371+
>this : Symbol(C13, Decl(strictPropertyInitialization.ts, 152, 1))
372+
>E.A : Symbol(E.A, Decl(strictPropertyInitialization.ts, 149, 8))
373+
>E : Symbol(E, Decl(strictPropertyInitialization.ts, 147, 1))
374+
>A : Symbol(E.A, Decl(strictPropertyInitialization.ts, 149, 8))
375+
}
376+
}
377+

‎tests/baselines/reference/strictPropertyInitialization.types

+32
Original file line numberDiff line numberDiff line change
@@ -395,3 +395,35 @@ class C12 {
395395
}
396396
}
397397

398+
enum E {
399+
>E : E
400+
401+
A = "A",
402+
>A : E.A
403+
>"A" : "A"
404+
405+
B = "B"
406+
>B : E.B
407+
>"B" : "B"
408+
}
409+
class C13 {
410+
>C13 : C13
411+
412+
[E.A]: number;
413+
>[E.A] : number
414+
>E.A : E.A
415+
>E : typeof E
416+
>A : E.A
417+
418+
constructor() {
419+
this[E.A] = 1;
420+
>this[E.A] = 1 : 1
421+
>this[E.A] : number
422+
>this : this
423+
>E.A : E.A
424+
>E : typeof E
425+
>A : E.A
426+
>1 : 1
427+
}
428+
}
429+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//// [typeGuardNarrowsIndexedAccessOfKnownProperty11.ts]
2+
enum E { A, B }
3+
4+
declare const m: { [K in E]: string | null };
5+
6+
if (m[E.A] !== null) {
7+
m[E.A].toString(); // string
8+
}
9+
10+
11+
//// [typeGuardNarrowsIndexedAccessOfKnownProperty11.js]
12+
"use strict";
13+
var E;
14+
(function (E) {
15+
E[E["A"] = 0] = "A";
16+
E[E["B"] = 1] = "B";
17+
})(E || (E = {}));
18+
if (m[E.A] !== null) {
19+
m[E.A].toString(); // string
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty11.ts ===
2+
enum E { A, B }
3+
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 0))
4+
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 8))
5+
>B : Symbol(E.B, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 11))
6+
7+
declare const m: { [K in E]: string | null };
8+
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 2, 13))
9+
>K : Symbol(K, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 2, 20))
10+
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 0))
11+
12+
if (m[E.A] !== null) {
13+
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 2, 13))
14+
>E.A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 8))
15+
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 0))
16+
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 8))
17+
18+
m[E.A].toString(); // string
19+
>m[E.A].toString : Symbol(String.toString, Decl(lib.es5.d.ts, --, --))
20+
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 2, 13))
21+
>E.A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 8))
22+
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 0))
23+
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 8))
24+
>toString : Symbol(String.toString, Decl(lib.es5.d.ts, --, --))
25+
}
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty11.ts ===
2+
enum E { A, B }
3+
>E : E
4+
>A : E.A
5+
>B : E.B
6+
7+
declare const m: { [K in E]: string | null };
8+
>m : { 0: string | null; 1: string | null; }
9+
>null : null
10+
11+
if (m[E.A] !== null) {
12+
>m[E.A] !== null : boolean
13+
>m[E.A] : string | null
14+
>m : { 0: string | null; 1: string | null; }
15+
>E.A : E.A
16+
>E : typeof E
17+
>A : E.A
18+
>null : null
19+
20+
m[E.A].toString(); // string
21+
>m[E.A].toString() : string
22+
>m[E.A].toString : () => string
23+
>m[E.A] : string
24+
>m : { 0: string | null; 1: string | null; }
25+
>E.A : E.A
26+
>E : typeof E
27+
>A : E.A
28+
>toString : () => string
29+
}
30+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [typeGuardNarrowsIndexedAccessOfKnownProperty12.ts]
2+
enum E {
3+
A = "A",
4+
B = "B"
5+
}
6+
7+
declare const m: { [K in E]: string | null };
8+
9+
if (m[E.A] !== null) {
10+
m[E.A].toString(); // string
11+
}
12+
13+
14+
//// [typeGuardNarrowsIndexedAccessOfKnownProperty12.js]
15+
"use strict";
16+
var E;
17+
(function (E) {
18+
E["A"] = "A";
19+
E["B"] = "B";
20+
})(E || (E = {}));
21+
if (m[E.A] !== null) {
22+
m[E.A].toString(); // string
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty12.ts ===
2+
enum E {
3+
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 0))
4+
5+
A = "A",
6+
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 8))
7+
8+
B = "B"
9+
>B : Symbol(E.B, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 1, 12))
10+
}
11+
12+
declare const m: { [K in E]: string | null };
13+
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 5, 13))
14+
>K : Symbol(K, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 5, 20))
15+
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 0))
16+
17+
if (m[E.A] !== null) {
18+
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 5, 13))
19+
>E.A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 8))
20+
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 0))
21+
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 8))
22+
23+
m[E.A].toString(); // string
24+
>m[E.A].toString : Symbol(String.toString, Decl(lib.es5.d.ts, --, --))
25+
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 5, 13))
26+
>E.A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 8))
27+
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 0))
28+
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 8))
29+
>toString : Symbol(String.toString, Decl(lib.es5.d.ts, --, --))
30+
}
31+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty12.ts ===
2+
enum E {
3+
>E : E
4+
5+
A = "A",
6+
>A : E.A
7+
>"A" : "A"
8+
9+
B = "B"
10+
>B : E.B
11+
>"B" : "B"
12+
}
13+
14+
declare const m: { [K in E]: string | null };
15+
>m : { A: string | null; B: string | null; }
16+
>null : null
17+
18+
if (m[E.A] !== null) {
19+
>m[E.A] !== null : boolean
20+
>m[E.A] : string | null
21+
>m : { A: string | null; B: string | null; }
22+
>E.A : E.A
23+
>E : typeof E
24+
>A : E.A
25+
>null : null
26+
27+
m[E.A].toString(); // string
28+
>m[E.A].toString() : string
29+
>m[E.A].toString : () => string
30+
>m[E.A] : string
31+
>m : { A: string | null; B: string | null; }
32+
>E.A : E.A
33+
>E : typeof E
34+
>A : E.A
35+
>toString : () => string
36+
}
37+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @strict: true
2+
3+
enum E { A, B }
4+
5+
declare const m: { [K in E]: string | null };
6+
7+
if (m[E.A] !== null) {
8+
m[E.A].toString(); // string
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @strict: true
2+
3+
enum E {
4+
A = "A",
5+
B = "B"
6+
}
7+
8+
declare const m: { [K in E]: string | null };
9+
10+
if (m[E.A] !== null) {
11+
m[E.A].toString(); // string
12+
}

‎tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts

+11
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,14 @@ class C12 {
150150
this['c'] = 1;
151151
}
152152
}
153+
154+
enum E {
155+
A = "A",
156+
B = "B"
157+
}
158+
class C13 {
159+
[E.A]: number;
160+
constructor() {
161+
this[E.A] = 1;
162+
}
163+
}

0 commit comments

Comments
 (0)
Please sign in to comment.