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
This commit is contained in:
Oleksandr T
2022-09-26 09:50:02 -07:00
committed by GitHub
parent bc9cbbef42
commit c81bf4d8b0
14 changed files with 306 additions and 2 deletions
+7 -2
View File
@@ -23665,7 +23665,7 @@ namespace ts {
}
if (isEntityNameExpression(node.argumentExpression)) {
const symbol = resolveEntityName(node.argumentExpression, SymbolFlags.Value, /*ignoreErrors*/ true);
if (!symbol || !isConstVariable(symbol)) return undefined;
if (!symbol || !(isConstVariable(symbol) || (symbol.flags & SymbolFlags.EnumMember))) return undefined;
const declaration = symbol.valueDeclaration;
if (declaration === undefined) return undefined;
@@ -23680,7 +23680,12 @@ namespace ts {
if (hasOnlyExpressionInitializer(declaration) && isBlockScopedNameDeclaredBeforeUse(declaration, node.argumentExpression)) {
const initializer = getEffectiveInitializer(declaration);
return initializer && tryGetNameFromType(getTypeOfExpression(initializer));
if (initializer) {
return tryGetNameFromType(getTypeOfExpression(initializer));
}
if (isEnumMember(declaration)) {
return getTextOfPropertyName(declaration.name);
}
}
}
return undefined;
@@ -179,4 +179,15 @@ tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitial
this['c'] = 1;
}
}
enum E {
A = "A",
B = "B"
}
class C13 {
[E.A]: number;
constructor() {
this[E.A] = 1;
}
}
@@ -147,6 +147,17 @@ class C12 {
this['c'] = 1;
}
}
enum E {
A = "A",
B = "B"
}
class C13 {
[E.A]: number;
constructor() {
this[E.A] = 1;
}
}
//// [strictPropertyInitialization.js]
@@ -259,6 +270,17 @@ class C12 {
this['c'] = 1;
}
}
var E;
(function (E) {
E["A"] = "A";
E["B"] = "B";
})(E || (E = {}));
class C13 {
constructor() {
this[E.A] = 1;
}
}
E.A;
//// [strictPropertyInitialization.d.ts]
@@ -335,3 +357,11 @@ declare class C12 {
['c']: number;
constructor();
}
declare enum E {
A = "A",
B = "B"
}
declare class C13 {
[E.A]: number;
constructor();
}
@@ -348,3 +348,30 @@ class C12 {
}
}
enum E {
>E : Symbol(E, Decl(strictPropertyInitialization.ts, 147, 1))
A = "A",
>A : Symbol(E.A, Decl(strictPropertyInitialization.ts, 149, 8))
B = "B"
>B : Symbol(E.B, Decl(strictPropertyInitialization.ts, 150, 12))
}
class C13 {
>C13 : Symbol(C13, Decl(strictPropertyInitialization.ts, 152, 1))
[E.A]: number;
>[E.A] : Symbol(C13[E.A], Decl(strictPropertyInitialization.ts, 153, 11))
>E.A : Symbol(E.A, Decl(strictPropertyInitialization.ts, 149, 8))
>E : Symbol(E, Decl(strictPropertyInitialization.ts, 147, 1))
>A : Symbol(E.A, Decl(strictPropertyInitialization.ts, 149, 8))
constructor() {
this[E.A] = 1;
>this : Symbol(C13, Decl(strictPropertyInitialization.ts, 152, 1))
>E.A : Symbol(E.A, Decl(strictPropertyInitialization.ts, 149, 8))
>E : Symbol(E, Decl(strictPropertyInitialization.ts, 147, 1))
>A : Symbol(E.A, Decl(strictPropertyInitialization.ts, 149, 8))
}
}
@@ -395,3 +395,35 @@ class C12 {
}
}
enum E {
>E : E
A = "A",
>A : E.A
>"A" : "A"
B = "B"
>B : E.B
>"B" : "B"
}
class C13 {
>C13 : C13
[E.A]: number;
>[E.A] : number
>E.A : E.A
>E : typeof E
>A : E.A
constructor() {
this[E.A] = 1;
>this[E.A] = 1 : 1
>this[E.A] : number
>this : this
>E.A : E.A
>E : typeof E
>A : E.A
>1 : 1
}
}
@@ -0,0 +1,20 @@
//// [typeGuardNarrowsIndexedAccessOfKnownProperty11.ts]
enum E { A, B }
declare const m: { [K in E]: string | null };
if (m[E.A] !== null) {
m[E.A].toString(); // string
}
//// [typeGuardNarrowsIndexedAccessOfKnownProperty11.js]
"use strict";
var E;
(function (E) {
E[E["A"] = 0] = "A";
E[E["B"] = 1] = "B";
})(E || (E = {}));
if (m[E.A] !== null) {
m[E.A].toString(); // string
}
@@ -0,0 +1,26 @@
=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty11.ts ===
enum E { A, B }
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 0))
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 8))
>B : Symbol(E.B, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 11))
declare const m: { [K in E]: string | null };
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 2, 13))
>K : Symbol(K, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 2, 20))
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 0))
if (m[E.A] !== null) {
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 2, 13))
>E.A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 8))
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 0))
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 8))
m[E.A].toString(); // string
>m[E.A].toString : Symbol(String.toString, Decl(lib.es5.d.ts, --, --))
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 2, 13))
>E.A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 8))
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 0))
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty11.ts, 0, 8))
>toString : Symbol(String.toString, Decl(lib.es5.d.ts, --, --))
}
@@ -0,0 +1,30 @@
=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty11.ts ===
enum E { A, B }
>E : E
>A : E.A
>B : E.B
declare const m: { [K in E]: string | null };
>m : { 0: string | null; 1: string | null; }
>null : null
if (m[E.A] !== null) {
>m[E.A] !== null : boolean
>m[E.A] : string | null
>m : { 0: string | null; 1: string | null; }
>E.A : E.A
>E : typeof E
>A : E.A
>null : null
m[E.A].toString(); // string
>m[E.A].toString() : string
>m[E.A].toString : () => string
>m[E.A] : string
>m : { 0: string | null; 1: string | null; }
>E.A : E.A
>E : typeof E
>A : E.A
>toString : () => string
}
@@ -0,0 +1,23 @@
//// [typeGuardNarrowsIndexedAccessOfKnownProperty12.ts]
enum E {
A = "A",
B = "B"
}
declare const m: { [K in E]: string | null };
if (m[E.A] !== null) {
m[E.A].toString(); // string
}
//// [typeGuardNarrowsIndexedAccessOfKnownProperty12.js]
"use strict";
var E;
(function (E) {
E["A"] = "A";
E["B"] = "B";
})(E || (E = {}));
if (m[E.A] !== null) {
m[E.A].toString(); // string
}
@@ -0,0 +1,31 @@
=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty12.ts ===
enum E {
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 0))
A = "A",
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 8))
B = "B"
>B : Symbol(E.B, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 1, 12))
}
declare const m: { [K in E]: string | null };
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 5, 13))
>K : Symbol(K, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 5, 20))
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 0))
if (m[E.A] !== null) {
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 5, 13))
>E.A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 8))
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 0))
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 8))
m[E.A].toString(); // string
>m[E.A].toString : Symbol(String.toString, Decl(lib.es5.d.ts, --, --))
>m : Symbol(m, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 5, 13))
>E.A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 8))
>E : Symbol(E, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 0))
>A : Symbol(E.A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty12.ts, 0, 8))
>toString : Symbol(String.toString, Decl(lib.es5.d.ts, --, --))
}
@@ -0,0 +1,37 @@
=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty12.ts ===
enum E {
>E : E
A = "A",
>A : E.A
>"A" : "A"
B = "B"
>B : E.B
>"B" : "B"
}
declare const m: { [K in E]: string | null };
>m : { A: string | null; B: string | null; }
>null : null
if (m[E.A] !== null) {
>m[E.A] !== null : boolean
>m[E.A] : string | null
>m : { A: string | null; B: string | null; }
>E.A : E.A
>E : typeof E
>A : E.A
>null : null
m[E.A].toString(); // string
>m[E.A].toString() : string
>m[E.A].toString : () => string
>m[E.A] : string
>m : { A: string | null; B: string | null; }
>E.A : E.A
>E : typeof E
>A : E.A
>toString : () => string
}
@@ -0,0 +1,9 @@
// @strict: true
enum E { A, B }
declare const m: { [K in E]: string | null };
if (m[E.A] !== null) {
m[E.A].toString(); // string
}
@@ -0,0 +1,12 @@
// @strict: true
enum E {
A = "A",
B = "B"
}
declare const m: { [K in E]: string | null };
if (m[E.A] !== null) {
m[E.A].toString(); // string
}
@@ -150,3 +150,14 @@ class C12 {
this['c'] = 1;
}
}
enum E {
A = "A",
B = "B"
}
class C13 {
[E.A]: number;
constructor() {
this[E.A] = 1;
}
}