Skip to content

Commit 03c5a37

Browse files
Andaristrbuckton
andauthored
Allow auto accessor types to be inferred from their flow types in constructors and static blocks (#59732)
Co-authored-by: Ron Buckton <[email protected]>
1 parent 3b0dfaa commit 03c5a37

28 files changed

+1314
-12
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12005,7 +12005,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1200512005
getAnnotatedAccessorType(setter) ||
1200612006
getAnnotatedAccessorType(accessor) ||
1200712007
getter && getter.body && getReturnTypeFromBody(getter) ||
12008-
accessor && accessor.initializer && getWidenedTypeForVariableLikeDeclaration(accessor, /*reportErrors*/ true);
12008+
accessor && getWidenedTypeForVariableLikeDeclaration(accessor, /*reportErrors*/ true);
1200912009
if (!type) {
1201012010
if (setter && !isPrivateWithinAmbient(setter)) {
1201112011
errorOrSuggestion(noImplicitAny, setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//// [tests/cases/compiler/classAccessorInitializationInferenceWithElementAccess1.ts] ////
2+
3+
//// [classAccessorInitializationInferenceWithElementAccess1.ts]
4+
export class Cls {
5+
accessor x;
6+
accessor y;
7+
accessor z;
8+
9+
accessor 0;
10+
11+
constructor(seed: number) {
12+
this['x'] = [seed];
13+
this['y'] = { seed };
14+
this['z'] = `${seed}`;
15+
16+
this[0] = [seed];
17+
}
18+
}
19+
20+
21+
//// [classAccessorInitializationInferenceWithElementAccess1.js]
22+
export class Cls {
23+
accessor x;
24+
accessor y;
25+
accessor z;
26+
accessor 0;
27+
constructor(seed) {
28+
this['x'] = [seed];
29+
this['y'] = { seed };
30+
this['z'] = `${seed}`;
31+
this[0] = [seed];
32+
}
33+
}
34+
35+
36+
//// [classAccessorInitializationInferenceWithElementAccess1.d.ts]
37+
export declare class Cls {
38+
accessor x: number[];
39+
accessor y: {
40+
seed: number;
41+
};
42+
accessor z: string;
43+
accessor 0: number[];
44+
constructor(seed: number);
45+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//// [tests/cases/compiler/classAccessorInitializationInferenceWithElementAccess1.ts] ////
2+
3+
=== classAccessorInitializationInferenceWithElementAccess1.ts ===
4+
export class Cls {
5+
>Cls : Symbol(Cls, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 0, 0))
6+
7+
accessor x;
8+
>x : Symbol(Cls.x, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 0, 18))
9+
10+
accessor y;
11+
>y : Symbol(Cls.y, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 1, 15))
12+
13+
accessor z;
14+
>z : Symbol(Cls.z, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 2, 15))
15+
16+
accessor 0;
17+
>0 : Symbol(Cls[0], Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 3, 15))
18+
19+
constructor(seed: number) {
20+
>seed : Symbol(seed, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 7, 16))
21+
22+
this['x'] = [seed];
23+
>this : Symbol(Cls, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 0, 0))
24+
>'x' : Symbol(Cls.x, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 0, 18))
25+
>seed : Symbol(seed, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 7, 16))
26+
27+
this['y'] = { seed };
28+
>this : Symbol(Cls, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 0, 0))
29+
>'y' : Symbol(Cls.y, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 1, 15))
30+
>seed : Symbol(seed, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 9, 21))
31+
32+
this['z'] = `${seed}`;
33+
>this : Symbol(Cls, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 0, 0))
34+
>'z' : Symbol(Cls.z, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 2, 15))
35+
>seed : Symbol(seed, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 7, 16))
36+
37+
this[0] = [seed];
38+
>this : Symbol(Cls, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 0, 0))
39+
>0 : Symbol(Cls[0], Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 3, 15))
40+
>seed : Symbol(seed, Decl(classAccessorInitializationInferenceWithElementAccess1.ts, 7, 16))
41+
}
42+
}
43+
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//// [tests/cases/compiler/classAccessorInitializationInferenceWithElementAccess1.ts] ////
2+
3+
=== classAccessorInitializationInferenceWithElementAccess1.ts ===
4+
export class Cls {
5+
>Cls : Cls
6+
> : ^^^
7+
8+
accessor x;
9+
>x : number[]
10+
> : ^^^^^^^^
11+
12+
accessor y;
13+
>y : { seed: number; }
14+
> : ^^^^^^^^^^^^^^^^^
15+
16+
accessor z;
17+
>z : string
18+
> : ^^^^^^
19+
20+
accessor 0;
21+
>0 : number[]
22+
> : ^^^^^^^^
23+
24+
constructor(seed: number) {
25+
>seed : number
26+
> : ^^^^^^
27+
28+
this['x'] = [seed];
29+
>this['x'] = [seed] : number[]
30+
> : ^^^^^^^^
31+
>this['x'] : number[]
32+
> : ^^^^^^^^
33+
>this : this
34+
> : ^^^^
35+
>'x' : "x"
36+
> : ^^^
37+
>[seed] : number[]
38+
> : ^^^^^^^^
39+
>seed : number
40+
> : ^^^^^^
41+
42+
this['y'] = { seed };
43+
>this['y'] = { seed } : { seed: number; }
44+
> : ^^^^^^^^^^^^^^^^^
45+
>this['y'] : { seed: number; }
46+
> : ^^^^^^^^^^^^^^^^^
47+
>this : this
48+
> : ^^^^
49+
>'y' : "y"
50+
> : ^^^
51+
>{ seed } : { seed: number; }
52+
> : ^^^^^^^^^^^^^^^^^
53+
>seed : number
54+
> : ^^^^^^
55+
56+
this['z'] = `${seed}`;
57+
>this['z'] = `${seed}` : string
58+
> : ^^^^^^
59+
>this['z'] : string
60+
> : ^^^^^^
61+
>this : this
62+
> : ^^^^
63+
>'z' : "z"
64+
> : ^^^
65+
>`${seed}` : string
66+
> : ^^^^^^
67+
>seed : number
68+
> : ^^^^^^
69+
70+
this[0] = [seed];
71+
>this[0] = [seed] : number[]
72+
> : ^^^^^^^^
73+
>this[0] : number[]
74+
> : ^^^^^^^^
75+
>this : this
76+
> : ^^^^
77+
>0 : 0
78+
> : ^
79+
>[seed] : number[]
80+
> : ^^^^^^^^
81+
>seed : number
82+
> : ^^^^^^
83+
}
84+
}
85+

tests/baselines/reference/classAttributeInferenceTemplate.js

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,42 @@ class MyClass {
1313

1414
const localProperty = `foo-${variable}`; // Correctly inferred as `string`
1515
}
16-
}
16+
}
17+
18+
class MyClass2 {
19+
accessor property;
20+
accessor property2;
21+
22+
constructor() {
23+
const variable = 'something'
24+
25+
this.property = `foo`; // Correctly inferred as `string`
26+
this.property2 = `foo-${variable}`; // Causes an error
27+
28+
const localProperty = `foo-${variable}`; // Correctly inferred as `string`
29+
}
30+
}
31+
1732

1833
//// [classAttributeInferenceTemplate.js]
1934
"use strict";
20-
var MyClass = /** @class */ (function () {
21-
function MyClass() {
22-
var variable = 'something';
23-
this.property = "foo"; // Correctly inferred as `string`
24-
this.property2 = "foo-".concat(variable); // Causes an error
25-
var localProperty = "foo-".concat(variable); // Correctly inferred as `string`
35+
class MyClass {
36+
property;
37+
property2;
38+
constructor() {
39+
const variable = 'something';
40+
this.property = `foo`; // Correctly inferred as `string`
41+
this.property2 = `foo-${variable}`; // Causes an error
42+
const localProperty = `foo-${variable}`; // Correctly inferred as `string`
2643
}
27-
return MyClass;
28-
}());
44+
}
45+
class MyClass2 {
46+
accessor property;
47+
accessor property2;
48+
constructor() {
49+
const variable = 'something';
50+
this.property = `foo`; // Correctly inferred as `string`
51+
this.property2 = `foo-${variable}`; // Causes an error
52+
const localProperty = `foo-${variable}`; // Correctly inferred as `string`
53+
}
54+
}

tests/baselines/reference/classAttributeInferenceTemplate.symbols

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,34 @@ class MyClass {
3030
>variable : Symbol(variable, Decl(classAttributeInferenceTemplate.ts, 5, 13))
3131
}
3232
}
33+
34+
class MyClass2 {
35+
>MyClass2 : Symbol(MyClass2, Decl(classAttributeInferenceTemplate.ts, 12, 1))
36+
37+
accessor property;
38+
>property : Symbol(MyClass2.property, Decl(classAttributeInferenceTemplate.ts, 14, 16))
39+
40+
accessor property2;
41+
>property2 : Symbol(MyClass2.property2, Decl(classAttributeInferenceTemplate.ts, 15, 22))
42+
43+
constructor() {
44+
const variable = 'something'
45+
>variable : Symbol(variable, Decl(classAttributeInferenceTemplate.ts, 19, 13))
46+
47+
this.property = `foo`; // Correctly inferred as `string`
48+
>this.property : Symbol(MyClass2.property, Decl(classAttributeInferenceTemplate.ts, 14, 16))
49+
>this : Symbol(MyClass2, Decl(classAttributeInferenceTemplate.ts, 12, 1))
50+
>property : Symbol(MyClass2.property, Decl(classAttributeInferenceTemplate.ts, 14, 16))
51+
52+
this.property2 = `foo-${variable}`; // Causes an error
53+
>this.property2 : Symbol(MyClass2.property2, Decl(classAttributeInferenceTemplate.ts, 15, 22))
54+
>this : Symbol(MyClass2, Decl(classAttributeInferenceTemplate.ts, 12, 1))
55+
>property2 : Symbol(MyClass2.property2, Decl(classAttributeInferenceTemplate.ts, 15, 22))
56+
>variable : Symbol(variable, Decl(classAttributeInferenceTemplate.ts, 19, 13))
57+
58+
const localProperty = `foo-${variable}`; // Correctly inferred as `string`
59+
>localProperty : Symbol(localProperty, Decl(classAttributeInferenceTemplate.ts, 24, 13))
60+
>variable : Symbol(variable, Decl(classAttributeInferenceTemplate.ts, 19, 13))
61+
}
62+
}
63+

tests/baselines/reference/classAttributeInferenceTemplate.types

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,59 @@ class MyClass {
5555
> : ^^^^^^^^^^^
5656
}
5757
}
58+
59+
class MyClass2 {
60+
>MyClass2 : MyClass2
61+
> : ^^^^^^^^
62+
63+
accessor property;
64+
>property : string
65+
> : ^^^^^^
66+
67+
accessor property2;
68+
>property2 : string
69+
> : ^^^^^^
70+
71+
constructor() {
72+
const variable = 'something'
73+
>variable : "something"
74+
> : ^^^^^^^^^^^
75+
>'something' : "something"
76+
> : ^^^^^^^^^^^
77+
78+
this.property = `foo`; // Correctly inferred as `string`
79+
>this.property = `foo` : "foo"
80+
> : ^^^^^
81+
>this.property : string
82+
> : ^^^^^^
83+
>this : this
84+
> : ^^^^
85+
>property : string
86+
> : ^^^^^^
87+
>`foo` : "foo"
88+
> : ^^^^^
89+
90+
this.property2 = `foo-${variable}`; // Causes an error
91+
>this.property2 = `foo-${variable}` : "foo-something"
92+
> : ^^^^^^^^^^^^^^^
93+
>this.property2 : string
94+
> : ^^^^^^
95+
>this : this
96+
> : ^^^^
97+
>property2 : string
98+
> : ^^^^^^
99+
>`foo-${variable}` : "foo-something"
100+
> : ^^^^^^^^^^^^^^^
101+
>variable : "something"
102+
> : ^^^^^^^^^^^
103+
104+
const localProperty = `foo-${variable}`; // Correctly inferred as `string`
105+
>localProperty : "foo-something"
106+
> : ^^^^^^^^^^^^^^^
107+
>`foo-${variable}` : "foo-something"
108+
> : ^^^^^^^^^^^^^^^
109+
>variable : "something"
110+
> : ^^^^^^^^^^^
111+
}
112+
}
113+

tests/baselines/reference/classAttributeInferenceTemplateJS.symbols

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,34 @@ class MyClass {
3030
>variable : Symbol(variable, Decl(index.js, 5, 13))
3131
}
3232
}
33+
34+
class MyClass2 {
35+
>MyClass2 : Symbol(MyClass2, Decl(index.js, 12, 1))
36+
37+
accessor property;
38+
>property : Symbol(MyClass2.property, Decl(index.js, 14, 16))
39+
40+
accessor property2;
41+
>property2 : Symbol(MyClass2.property2, Decl(index.js, 15, 22))
42+
43+
constructor() {
44+
const variable = 'something'
45+
>variable : Symbol(variable, Decl(index.js, 19, 13))
46+
47+
this.property = `foo`; // Correctly inferred as `string`
48+
>this.property : Symbol(MyClass2.property, Decl(index.js, 14, 16))
49+
>this : Symbol(MyClass2, Decl(index.js, 12, 1))
50+
>property : Symbol(MyClass2.property, Decl(index.js, 14, 16))
51+
52+
this.property2 = `foo-${variable}`; // Causes an error
53+
>this.property2 : Symbol(MyClass2.property2, Decl(index.js, 15, 22))
54+
>this : Symbol(MyClass2, Decl(index.js, 12, 1))
55+
>property2 : Symbol(MyClass2.property2, Decl(index.js, 15, 22))
56+
>variable : Symbol(variable, Decl(index.js, 19, 13))
57+
58+
const localProperty = `foo-${variable}`; // Correctly inferred as `string`
59+
>localProperty : Symbol(localProperty, Decl(index.js, 24, 13))
60+
>variable : Symbol(variable, Decl(index.js, 19, 13))
61+
}
62+
}
63+

0 commit comments

Comments
 (0)