Skip to content

Commit 3ce08c6

Browse files
fix(49223): checker.getTypeAtLocation for ExpressionWithTypeArguments returns an error any type (#49284) (#49369)
* fix(49223): handle ExpressionWithTypeArguments nodes in isExpressionNode * Update src/compiler/utilities.ts * Just use `!isHeritageClause(node.parent)`. Co-authored-by: Daniel Rosenwasser <[email protected]> Co-authored-by: Oleksandr T <[email protected]>
1 parent 3bf0d30 commit 3ce08c6

8 files changed

+80
-0
lines changed

Diff for: src/compiler/utilities.ts

+2
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,8 @@ namespace ts {
20162016
case SyntaxKind.AwaitExpression:
20172017
case SyntaxKind.MetaProperty:
20182018
return true;
2019+
case SyntaxKind.ExpressionWithTypeArguments:
2020+
return !isHeritageClause(node.parent);
20192021
case SyntaxKind.QualifiedName:
20202022
while (node.parent.kind === SyntaxKind.QualifiedName) {
20212023
node = node.parent;

Diff for: src/testRunner/unittests/publicApi.ts

+24
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,30 @@ describe("unittests:: Public APIs:: getTypeAtLocation", () => {
131131
assert.equal(type.flags, ts.TypeFlags.Any);
132132
});
133133

134+
it("works on ExpressionWithTypeArguments", () => {
135+
const content = `
136+
function fn<T>(value: T) {
137+
return { value };
138+
}
139+
const foo = fn<string>;
140+
`;
141+
const host = new fakes.CompilerHost(vfs.createFromFileSystem(
142+
Harness.IO,
143+
/*ignoreCase*/ true,
144+
{ documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" }));
145+
146+
const program = ts.createProgram({
147+
host,
148+
rootNames: ["/file.ts"],
149+
options: { noLib: true }
150+
});
151+
152+
const checker = program.getTypeChecker();
153+
const file = program.getSourceFile("/file.ts")!;
154+
const [declaration] = (ts.findLast(file.statements, ts.isVariableStatement) as ts.VariableStatement).declarationList.declarations;
155+
assert.equal(checker.getTypeAtLocation(declaration.initializer!).flags, ts.TypeFlags.Object);
156+
});
157+
134158
it("returns an errorType for VariableDeclaration with BindingPattern name", () => {
135159
const content = "const foo = [1];\n" + "const [a] = foo;";
136160

Diff for: tests/baselines/reference/genericCallWithoutArgs.types

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ function f<X, Y>(x: X, y: Y) {
77

88
f<number,string>.
99
>f<number,string>. : any
10+
>f<number,string> : (x: number, y: string) => void
1011
>f : <X, Y>(x: X, y: Y) => void
1112
> : any
1213

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
=== tests/cases/conformance/types/import/importWithTypeArguments.ts ===
22
import<T>
3+
>import<T> : any
4+
35
const a = import<string, number>
46
>a : any
7+
>import<string, number> : any
58

Diff for: tests/baselines/reference/instantiationExpressionErrors.types

+13
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,34 @@ declare let f: { <T>(): T, g<U>(): U };
77

88
const a1 = f<number>; // { (): number; g<U>(): U; }
99
>a1 : { (): number; g<U>(): U; }
10+
>f<number> : { (): number; g<U>(): U; }
1011
>f : { <T>(): T; g<U>(): U; }
1112

1213
const a2 = f.g<number>; // () => number
1314
>a2 : () => number
15+
>f.g<number> : () => number
1416
>f.g : <U>() => U
1517
>f : { <T>(): T; g<U>(): U; }
1618
>g : <U>() => U
1719

1820
const a3 = f<number>.g; // <U>() => U
1921
>a3 : <U>() => U
2022
>f<number>.g : <U>() => U
23+
>f<number> : { (): number; g<U>(): U; }
2124
>f : { <T>(): T; g<U>(): U; }
2225
>g : <U>() => U
2326

2427
const a4 = f<number>.g<number>; // () => number
2528
>a4 : () => number
29+
>f<number>.g<number> : () => number
2630
>f<number>.g : <U>() => U
31+
>f<number> : { (): number; g<U>(): U; }
2732
>f : { <T>(): T; g<U>(): U; }
2833
>g : <U>() => U
2934

3035
const a5 = f['g']<number>; // () => number
3136
>a5 : () => number
37+
>f['g']<number> : () => number
3238
>f['g'] : <U>() => U
3339
>f : { <T>(): T; g<U>(): U; }
3440
>'g' : "g"
@@ -48,6 +54,7 @@ const a7 = (f<number>)['g'];
4854
>a7 : <U>() => U
4955
>(f<number>)['g'] : <U>() => U
5056
>(f<number>) : { (): number; g<U>(): U; }
57+
>f<number> : { (): number; g<U>(): U; }
5158
>f : { <T>(): T; g<U>(): U; }
5259
>'g' : "g"
5360

@@ -64,7 +71,9 @@ const a8 = f<number><number>; // Relational operator error
6471

6572
const a9 = (f<number>)<number>; // Error, no applicable signatures
6673
>a9 : { g<U>(): U; }
74+
>(f<number>)<number> : { g<U>(): U; }
6775
>(f<number>) : { (): number; g<U>(): U; }
76+
>f<number> : { (): number; g<U>(): U; }
6877
>f : { <T>(): T; g<U>(): U; }
6978

7079
// Type arguments with `?.` token
@@ -82,11 +91,13 @@ const b2 = f?.<number>();
8291
const b3 = f<number>?.();
8392
>b3 : number
8493
>f<number>?.() : number
94+
>f<number> : { (): number; g<U>(): U; }
8595
>f : { <T>(): T; g<U>(): U; }
8696

8797
const b4 = f<number>?.<number>(); // Error, expected no type arguments
8898
>b4 : number
8999
>f<number>?.<number>() : number
100+
>f<number> : { (): number; g<U>(): U; }
90101
>f : { <T>(): T; g<U>(): U; }
91102

92103
// Parsed as function call, even though this differs from JavaScript
@@ -116,6 +127,7 @@ true;
116127

117128
const x3 = f<true>;
118129
>x3 : { (): true; g<U>(): U; }
130+
>f<true> : { (): true; g<U>(): U; }
119131
>f : { <T>(): T; g<U>(): U; }
120132
>true : true
121133

@@ -126,6 +138,7 @@ true;
126138

127139
const x4 = f<true>
128140
>x4 : { (): true; g<U>(): U; }
141+
>f<true> : { (): true; g<U>(): U; }
129142
>f : { <T>(): T; g<U>(): U; }
130143
>true : true
131144

Diff for: tests/baselines/reference/instantiationExpressions.types

+34
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,22 @@ function f1() {
1717

1818
let f0 = fx<>; // Error
1919
>f0 : { <T>(x: T): T; <T>(x: T, n: number): T; <T, U>(t: [T, U]): [T, U]; }
20+
>fx<> : { <T>(x: T): T; <T>(x: T, n: number): T; <T, U>(t: [T, U]): [T, U]; }
2021
>fx : { <T>(x: T): T; <T>(x: T, n: number): T; <T, U>(t: [T, U]): [T, U]; }
2122

2223
let f1 = fx<string>; // { (x: string): string; (x: string, n: number): string; }
2324
>f1 : { (x: string): string; (x: string, n: number): string; }
25+
>fx<string> : { (x: string): string; (x: string, n: number): string; }
2426
>fx : { <T>(x: T): T; <T>(x: T, n: number): T; <T, U>(t: [T, U]): [T, U]; }
2527

2628
let f2 = fx<string, number>; // (t: [string, number]) => [string, number]
2729
>f2 : (t: [string, number]) => [string, number]
30+
>fx<string, number> : (t: [string, number]) => [string, number]
2831
>fx : { <T>(x: T): T; <T>(x: T, n: number): T; <T, U>(t: [T, U]): [T, U]; }
2932

3033
let f3 = fx<string, number, boolean>; // Error
3134
>f3 : {}
35+
>fx<string, number, boolean> : {}
3236
>fx : { <T>(x: T): T; <T>(x: T, n: number): T; <T, U>(t: [T, U]): [T, U]; }
3337
}
3438

@@ -53,14 +57,17 @@ function f2() {
5357

5458
const A0 = Array<>; // Error
5559
>A0 : ArrayConstructor
60+
>Array<> : ArrayConstructor
5661
>Array : ArrayConstructor
5762

5863
const A1 = Array<string>; // new (...) => string[]
5964
>A1 : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
65+
>Array<string> : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
6066
>Array : ArrayConstructor
6167

6268
const A2 = Array<string, number>; // Error
6369
>A2 : { isArray(arg: any): arg is any[]; readonly prototype: any[]; }
70+
>Array<string, number> : { isArray(arg: any): arg is any[]; readonly prototype: any[]; }
6471
>Array : ArrayConstructor
6572
}
6673

@@ -92,10 +99,12 @@ function f3() {
9299

93100
let c1 = C<string>; // { new (x: string): C<string>; f<U>(x: U): T[]; prototype: C<any>; }
94101
>c1 : { new (x: string): C<string>; prototype: C<any>; f<U>(x: U): U[]; }
102+
>C<string> : { new (x: string): C<string>; prototype: C<any>; f<U>(x: U): U[]; }
95103
>C : typeof C
96104

97105
let f1 = C.f<string>; // (x: string) => string[]
98106
>f1 : (x: string) => string[]
107+
>C.f<string> : (x: string) => string[]
99108
>C.f : <U>(x: U) => U[]
100109
>C : typeof C
101110
>f : <U>(x: U) => U[]
@@ -110,6 +119,7 @@ function f10(f: { <T>(a: T): T, <U>(a: U, b: number): U[] }) {
110119

111120
let fs = f<string>; // { (a: string): string; (a: string, b: number): string[]; }
112121
>fs : { (a: string): string; (a: string, b: number): string[]; }
122+
>f<string> : { (a: string): string; (a: string, b: number): string[]; }
113123
>f : { <T>(a: T): T; <U>(a: U, b: number): U[]; }
114124
}
115125

@@ -122,6 +132,7 @@ function f11(f: { <T>(a: T): T, (a: string, b: number): string[] }) {
122132

123133
let fs = f<string>; // (a: string) => string
124134
>fs : (a: string) => string
135+
>f<string> : (a: string) => string
125136
>f : { <T>(a: T): T; (a: string, b: number): string[]; }
126137
}
127138

@@ -133,6 +144,7 @@ function f12(f: { <T>(a: T): T, x: string }) {
133144

134145
let fs = f<string>; // { (a: string): string; x: string; }
135146
>fs : { (a: string): string; x: string; }
147+
>f<string> : { (a: string): string; x: string; }
136148
>f : { <T>(a: T): T; x: string; }
137149
}
138150

@@ -144,6 +156,7 @@ function f13(f: { x: string, y: string }) {
144156

145157
let fs = f<string>; // Error, no applicable signatures
146158
>fs : { x: string; y: string; }
159+
>f<string> : { x: string; y: string; }
147160
>f : { x: string; y: string; }
148161
}
149162

@@ -156,6 +169,7 @@ function f14(f: { new <T>(a: T): T, new <U>(a: U, b: number): U[] }) {
156169

157170
let fs = f<string>; // { new (a: string): string; new (a: string, b: number): string[]; }
158171
>fs : { new (a: string): string; new (a: string, b: number): string[]; }
172+
>f<string> : { new (a: string): string; new (a: string, b: number): string[]; }
159173
>f : { new <T>(a: T): T; new <U>(a: U, b: number): U[]; }
160174
}
161175

@@ -168,6 +182,7 @@ function f15(f: { new <T>(a: T): T, <U>(a: U, b: number): U[] }) {
168182

169183
let fs = f<string>; // { new (a: string): string; (a: string, b: number): string[]; }
170184
>fs : { (a: string, b: number): string[]; new (a: string): string; }
185+
>f<string> : { (a: string, b: number): string[]; new (a: string): string; }
171186
>f : { <U>(a: U, b: number): U[]; new <T>(a: T): T; }
172187
}
173188

@@ -180,6 +195,7 @@ function f16(f: { new <T>(a: T): T, (a: string, b: number): string[] }) {
180195

181196
let fs = f<string>; // new (a: string) => string
182197
>fs : new (a: string) => string
198+
>f<string> : new (a: string) => string
183199
>f : { (a: string, b: number): string[]; new <T>(a: T): T; }
184200
}
185201

@@ -192,6 +208,7 @@ function f17(f: { <T>(a: T): T, new (a: string, b: number): string[] }) {
192208

193209
let fs = f<string>; // (a: string) => string
194210
>fs : (a: string) => string
211+
>f<string> : (a: string) => string
195212
>f : { <T>(a: T): T; new (a: string, b: number): string[]; }
196213
}
197214

@@ -204,6 +221,7 @@ function f20(f: (<T>(a: T) => T) & (<U>(a: U, b: number) => U[])) {
204221

205222
let fs = f<string>; // ((a: string) => string) & ((a: string, b: number) => string[]])
206223
>fs : ((a: string) => string) & ((a: string, b: number) => string[])
224+
>f<string> : ((a: string) => string) & ((a: string, b: number) => string[])
207225
>f : (<T>(a: T) => T) & (<U>(a: U, b: number) => U[])
208226
}
209227

@@ -216,6 +234,7 @@ function f21(f: (<T>(a: T) => T) & ((a: string, b: number) => string[])) {
216234

217235
let fs = f<string>; // (a: string) => string
218236
>fs : (a: string) => string
237+
>f<string> : (a: string) => string
219238
>f : (<T>(a: T) => T) & ((a: string, b: number) => string[])
220239
}
221240

@@ -227,6 +246,7 @@ function f22(f: (<T>(a: T) => T) & { x: string }) {
227246

228247
let fs = f<string>; // ((a: string) => string) & { x: string }
229248
>fs : ((a: string) => string) & { x: string; }
249+
>f<string> : ((a: string) => string) & { x: string; }
230250
>f : (<T>(a: T) => T) & { x: string; }
231251
}
232252

@@ -238,6 +258,7 @@ function f23(f: { x: string } & { y: string }) {
238258

239259
let fs = f<string>; // Error, no applicable signatures
240260
>fs : { x: string; } & { y: string; }
261+
>f<string> : { x: string; } & { y: string; }
241262
>f : { x: string; } & { y: string; }
242263
}
243264

@@ -250,6 +271,7 @@ function f24(f: (new <T>(a: T) => T) & (new <U>(a: U, b: number) => U[])) {
250271

251272
let fs = f<string>; // (new (a: string) => string) & ((a: string, b: number) => string[]])
252273
>fs : (new (a: string) => string) & (new (a: string, b: number) => string[])
274+
>f<string> : (new (a: string) => string) & (new (a: string, b: number) => string[])
253275
>f : (new <T>(a: T) => T) & (new <U>(a: U, b: number) => U[])
254276
}
255277

@@ -262,6 +284,7 @@ function f25(f: (new <T>(a: T) => T) & (<U>(a: U, b: number) => U[])) {
262284

263285
let fs = f<string>; // (new (a: string) => string) & ((a: string, b: number) => string[]])
264286
>fs : (new (a: string) => string) & ((a: string, b: number) => string[])
287+
>f<string> : (new (a: string) => string) & ((a: string, b: number) => string[])
265288
>f : (new <T>(a: T) => T) & (<U>(a: U, b: number) => U[])
266289
}
267290

@@ -274,6 +297,7 @@ function f26(f: (new <T>(a: T) => T) & ((a: string, b: number) => string[])) {
274297

275298
let fs = f<string>; // new (a: string) => string
276299
>fs : new (a: string) => string
300+
>f<string> : new (a: string) => string
277301
>f : (new <T>(a: T) => T) & ((a: string, b: number) => string[])
278302
}
279303

@@ -286,6 +310,7 @@ function f27(f: (<T>(a: T) => T) & (new (a: string, b: number) => string[])) {
286310

287311
let fs = f<string>; // (a: string) => string
288312
>fs : (a: string) => string
313+
>f<string> : (a: string) => string
289314
>f : (<T>(a: T) => T) & (new (a: string, b: number) => string[])
290315
}
291316

@@ -298,6 +323,7 @@ function f30(f: (<T>(a: T) => T) | (<U>(a: U, b: number) => U[])) {
298323

299324
let fs = f<string>; // ((a: string) => string) | ((a: string, b: number) => string[]])
300325
>fs : ((a: string) => string) | ((a: string, b: number) => string[])
326+
>f<string> : ((a: string) => string) | ((a: string, b: number) => string[])
301327
>f : (<T>(a: T) => T) | (<U>(a: U, b: number) => U[])
302328
}
303329

@@ -310,6 +336,7 @@ function f31(f: (<T>(a: T) => T) | ((a: string, b: number) => string[])) {
310336

311337
let fs = f<string>; // Error, '(a: string, b: number) => string[]' has no applicable signatures
312338
>fs : ((a: string) => string) | {}
339+
>f<string> : ((a: string) => string) | {}
313340
>f : (<T>(a: T) => T) | ((a: string, b: number) => string[])
314341
}
315342

@@ -321,6 +348,7 @@ function f32(f: (<T>(a: T) => T) | { x: string }) {
321348

322349
let fs = f<string>; // ((a: string) => string) | { x: string }
323350
>fs : { x: string; } | ((a: string) => string)
351+
>f<string> : { x: string; } | ((a: string) => string)
324352
>f : { x: string; } | (<T>(a: T) => T)
325353
}
326354

@@ -332,6 +360,7 @@ function f33(f: { x: string } | { y: string }) {
332360

333361
let fs = f<string>; // Error, no applicable signatures
334362
>fs : { x: string; } | { y: string; }
363+
>f<string> : { x: string; } | { y: string; }
335364
>f : { x: string; } | { y: string; }
336365
}
337366

@@ -344,6 +373,7 @@ function f34(f: (new <T>(a: T) => T) | (new <U>(a: U, b: number) => U[])) {
344373

345374
let fs = f<string>; // (new (a: string) => string) | ((a: string, b: number) => string[]])
346375
>fs : (new (a: string) => string) | (new (a: string, b: number) => string[])
376+
>f<string> : (new (a: string) => string) | (new (a: string, b: number) => string[])
347377
>f : (new <T>(a: T) => T) | (new <U>(a: U, b: number) => U[])
348378
}
349379

@@ -356,6 +386,7 @@ function f35(f: (new <T>(a: T) => T) | (<U>(a: U, b: number) => U[])) {
356386

357387
let fs = f<string>; // (new (a: string) => string) | ((a: string, b: number) => string[]])
358388
>fs : (new (a: string) => string) | ((a: string, b: number) => string[])
389+
>f<string> : (new (a: string) => string) | ((a: string, b: number) => string[])
359390
>f : (new <T>(a: T) => T) | (<U>(a: U, b: number) => U[])
360391
}
361392

@@ -368,6 +399,7 @@ function f36(f: (new <T>(a: T) => T) | ((a: string, b: number) => string[])) {
368399

369400
let fs = f<string>; // Error, '(a: string, b: number) => string[]' has no applicable signatures
370401
>fs : (new (a: string) => string) | {}
402+
>f<string> : (new (a: string) => string) | {}
371403
>f : (new <T>(a: T) => T) | ((a: string, b: number) => string[])
372404
}
373405

@@ -380,6 +412,7 @@ function f37(f: (<T>(a: T) => T) | (new (a: string, b: number) => string[])) {
380412

381413
let fs = f<string>; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures
382414
>fs : ((a: string) => string) | {}
415+
>f<string> : ((a: string) => string) | {}
383416
>f : (<T>(a: T) => T) | (new (a: string, b: number) => string[])
384417
}
385418

@@ -392,6 +425,7 @@ function f38<T extends (<A>(x: A) => A) | (<B>(x: B) => B[]), U>(f: T | U | (<C>
392425

393426
let fs = f<string>; // U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][])
394427
>fs : U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][])
428+
>f<string> : U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][])
395429
>f : T | U | (<C>(x: C) => C[][])
396430
}
397431

0 commit comments

Comments
 (0)