Fixed initializaiton-time inference for class properties assigned through element access (#49374)

This commit is contained in:
Mateusz Burzyński
2022-07-13 14:43:23 -07:00
committed by GitHub
parent 6aad28f174
commit 2ef3901940
4 changed files with 121 additions and 0 deletions
+8
View File
@@ -26907,6 +26907,14 @@ namespace ts {
const lhsType = getTypeOfExpression(e.expression);
return isPrivateIdentifier(e.name) ? tryGetPrivateIdentifierPropertyOfType(lhsType, e.name) : getPropertyOfType(lhsType, e.name.escapedText);
}
if (isElementAccessExpression(e)) {
const propType = checkExpressionCached(e.argumentExpression);
if (!isTypeUsableAsPropertyName(propType)) {
return undefined;
}
const lhsType = getTypeOfExpression(e.expression);
return getPropertyOfType(lhsType, getPropertyNameFromType(propType));
}
return undefined;
function tryGetPrivateIdentifierPropertyOfType(type: Type, id: PrivateIdentifier) {
@@ -0,0 +1,41 @@
=== tests/cases/compiler/classPropInitializationInferenceWithElementAccess.ts ===
// repro #49339
export class Cls {
>Cls : Symbol(Cls, Decl(classPropInitializationInferenceWithElementAccess.ts, 0, 0))
x;
>x : Symbol(Cls.x, Decl(classPropInitializationInferenceWithElementAccess.ts, 1, 18))
y;
>y : Symbol(Cls.y, Decl(classPropInitializationInferenceWithElementAccess.ts, 2, 6))
z;
>z : Symbol(Cls.z, Decl(classPropInitializationInferenceWithElementAccess.ts, 3, 6))
0;
>0 : Symbol(Cls[0], Decl(classPropInitializationInferenceWithElementAccess.ts, 4, 6))
constructor(seed: number) {
>seed : Symbol(seed, Decl(classPropInitializationInferenceWithElementAccess.ts, 8, 16))
this['x'] = [seed];
>this : Symbol(Cls, Decl(classPropInitializationInferenceWithElementAccess.ts, 0, 0))
>'x' : Symbol(Cls.x, Decl(classPropInitializationInferenceWithElementAccess.ts, 1, 18))
>seed : Symbol(seed, Decl(classPropInitializationInferenceWithElementAccess.ts, 8, 16))
this['y'] = { seed };
>this : Symbol(Cls, Decl(classPropInitializationInferenceWithElementAccess.ts, 0, 0))
>'y' : Symbol(Cls.y, Decl(classPropInitializationInferenceWithElementAccess.ts, 2, 6))
>seed : Symbol(seed, Decl(classPropInitializationInferenceWithElementAccess.ts, 10, 21))
this['z'] = `${seed}`;
>this : Symbol(Cls, Decl(classPropInitializationInferenceWithElementAccess.ts, 0, 0))
>'z' : Symbol(Cls.z, Decl(classPropInitializationInferenceWithElementAccess.ts, 3, 6))
>seed : Symbol(seed, Decl(classPropInitializationInferenceWithElementAccess.ts, 8, 16))
this[0] = [seed];
>this : Symbol(Cls, Decl(classPropInitializationInferenceWithElementAccess.ts, 0, 0))
>0 : Symbol(Cls[0], Decl(classPropInitializationInferenceWithElementAccess.ts, 4, 6))
>seed : Symbol(seed, Decl(classPropInitializationInferenceWithElementAccess.ts, 8, 16))
}
}
@@ -0,0 +1,53 @@
=== tests/cases/compiler/classPropInitializationInferenceWithElementAccess.ts ===
// repro #49339
export class Cls {
>Cls : Cls
x;
>x : number[]
y;
>y : { seed: number; }
z;
>z : string
0;
>0 : number[]
constructor(seed: number) {
>seed : number
this['x'] = [seed];
>this['x'] = [seed] : number[]
>this['x'] : number[]
>this : this
>'x' : "x"
>[seed] : number[]
>seed : number
this['y'] = { seed };
>this['y'] = { seed } : { seed: number; }
>this['y'] : { seed: number; }
>this : this
>'y' : "y"
>{ seed } : { seed: number; }
>seed : number
this['z'] = `${seed}`;
>this['z'] = `${seed}` : string
>this['z'] : string
>this : this
>'z' : "z"
>`${seed}` : string
>seed : number
this[0] = [seed];
>this[0] = [seed] : number[]
>this[0] : number[]
>this : this
>0 : 0
>[seed] : number[]
>seed : number
}
}
@@ -0,0 +1,19 @@
// @noEmit: true
// @strict: true
// repro #49339
export class Cls {
x;
y;
z;
0;
constructor(seed: number) {
this['x'] = [seed];
this['y'] = { seed };
this['z'] = `${seed}`;
this[0] = [seed];
}
}