Skip to content

Commit 1d026a9

Browse files
authored
Only resolve source return type when actually needed during inference (#58650)
1 parent af3a61f commit 1d026a9

7 files changed

+90
-21
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25172,13 +25172,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2517225172
}
2517325173

2517425174
function applyToReturnTypes(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) {
25175-
const sourceTypePredicate = getTypePredicateOfSignature(source);
2517625175
const targetTypePredicate = getTypePredicateOfSignature(target);
25177-
if (sourceTypePredicate && targetTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) {
25178-
callback(sourceTypePredicate.type, targetTypePredicate.type);
25176+
if (targetTypePredicate) {
25177+
const sourceTypePredicate = getTypePredicateOfSignature(source);
25178+
if (sourceTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) {
25179+
callback(sourceTypePredicate.type, targetTypePredicate.type);
25180+
return;
25181+
}
2517925182
}
25180-
else {
25181-
callback(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
25183+
const targetReturnType = getReturnTypeOfSignature(target);
25184+
if (couldContainTypeVariables(targetReturnType)) {
25185+
callback(getReturnTypeOfSignature(source), targetReturnType);
2518225186
}
2518325187
}
2518425188

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
circularReferenceInReturnType.ts(3,7): error TS7022: 'res1' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
22
circularReferenceInReturnType.ts(3,18): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
3-
circularReferenceInReturnType.ts(9,7): error TS7022: 'res3' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
4-
circularReferenceInReturnType.ts(9,20): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
53

64

7-
==== circularReferenceInReturnType.ts (4 errors) ====
5+
==== circularReferenceInReturnType.ts (2 errors) ====
86
// inference fails for res1 and res2, but ideally should not
97
declare function fn1<T>(cb: () => T): string;
108
const res1 = fn1(() => res1);
@@ -18,8 +16,14 @@ circularReferenceInReturnType.ts(9,20): error TS7024: Function implicitly has re
1816

1917
declare function fn3<T>(): <T2>(cb: (arg: T2) => any) => (a: T) => void;
2018
const res3 = fn3()(() => res3);
21-
~~~~
22-
!!! error TS7022: 'res3' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
23-
~~~~~~~~~~
24-
!!! error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
19+
20+
// https://github.com/microsoft/TypeScript/issues/58616
21+
22+
function foo(arg: Parameters<typeof bar>[0]) {
23+
return arg;
24+
}
25+
26+
function bar(arg: string) {
27+
return foo(arg);
28+
}
2529

tests/baselines/reference/circularReferenceInReturnType.symbols

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,24 @@ const res3 = fn3()(() => res3);
4040
>fn3 : Symbol(fn3, Decl(circularReferenceInReturnType.ts, 5, 31))
4141
>res3 : Symbol(res3, Decl(circularReferenceInReturnType.ts, 8, 5))
4242

43+
// https://github.com/microsoft/TypeScript/issues/58616
44+
45+
function foo(arg: Parameters<typeof bar>[0]) {
46+
>foo : Symbol(foo, Decl(circularReferenceInReturnType.ts, 8, 31))
47+
>arg : Symbol(arg, Decl(circularReferenceInReturnType.ts, 12, 13))
48+
>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --))
49+
>bar : Symbol(bar, Decl(circularReferenceInReturnType.ts, 14, 1))
50+
51+
return arg;
52+
>arg : Symbol(arg, Decl(circularReferenceInReturnType.ts, 12, 13))
53+
}
54+
55+
function bar(arg: string) {
56+
>bar : Symbol(bar, Decl(circularReferenceInReturnType.ts, 14, 1))
57+
>arg : Symbol(arg, Decl(circularReferenceInReturnType.ts, 16, 13))
58+
59+
return foo(arg);
60+
>foo : Symbol(foo, Decl(circularReferenceInReturnType.ts, 8, 31))
61+
>arg : Symbol(arg, Decl(circularReferenceInReturnType.ts, 16, 13))
62+
}
63+

tests/baselines/reference/circularReferenceInReturnType.types

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,46 @@ declare function fn3<T>(): <T2>(cb: (arg: T2) => any) => (a: T) => void;
5353
> : ^
5454

5555
const res3 = fn3()(() => res3);
56-
>res3 : any
57-
> : ^^^
56+
>res3 : (a: unknown) => void
57+
> : ^ ^^^^^^^^^^^^^^
5858
>fn3()(() => res3) : (a: unknown) => void
5959
> : ^ ^^^^^^^^^^^^^^
6060
>fn3() : <T2>(cb: (arg: T2) => any) => (a: unknown) => void
6161
> : ^^^^^ ^^^ ^^^^^^^^^ ^^^^^ ^^^^^^^
6262
>fn3 : <T>() => <T2>(cb: (arg: T2) => any) => (a: T) => void
6363
> : ^ ^^^^^^^
64-
>() => res3 : () => any
65-
> : ^^^^^^^^^
66-
>res3 : any
67-
> : ^^^
64+
>() => res3 : () => (a: unknown) => void
65+
> : ^^^^^^^ ^^^^^^^^^^^^^^
66+
>res3 : (a: unknown) => void
67+
> : ^ ^^^^^^^^^^^^^^
68+
69+
// https://github.com/microsoft/TypeScript/issues/58616
70+
71+
function foo(arg: Parameters<typeof bar>[0]) {
72+
>foo : (arg: Parameters<typeof bar>[0]) => string
73+
> : ^ ^^ ^^^^^^^^^^^
74+
>arg : string
75+
> : ^^^^^^
76+
>bar : (arg: string) => string
77+
> : ^ ^^ ^^^^^^^^^^^
78+
79+
return arg;
80+
>arg : string
81+
> : ^^^^^^
82+
}
83+
84+
function bar(arg: string) {
85+
>bar : (arg: string) => string
86+
> : ^ ^^ ^^^^^^^^^^^
87+
>arg : string
88+
> : ^^^^^^
89+
90+
return foo(arg);
91+
>foo(arg) : string
92+
> : ^^^^^^
93+
>foo : (arg: Parameters<typeof bar>[0]) => string
94+
> : ^ ^^ ^^^^^^^^^^^
95+
>arg : string
96+
> : ^^^^^^
97+
}
6898

tests/baselines/reference/complexRecursiveCollections.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
=== Performance Stats ===
44
Assignability cache: 10,000
55
Type Count: 50,000
6-
Instantiation count: 250,000
6+
Instantiation count: 100,000
77
Symbol count: 100,000
88

99
=== complex.ts ===

tests/baselines/reference/flatArrayNoExcessiveStackDepth.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
flatArrayNoExcessiveStackDepth.ts(20,5): error TS2322: Type 'FlatArray<Arr, any>' is not assignable to type 'FlatArray<Arr, D>'.
22
Type 'Arr' is not assignable to type 'FlatArray<Arr, D>'.
3-
Type 'Arr' is not assignable to type '(Arr extends readonly (infer InnerArr)[] ? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][D]> : Arr) & Arr'.
3+
Type 'Arr' is not assignable to type 'Arr & (Arr extends readonly (infer InnerArr)[] ? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][D]> : Arr)'.
44
Type 'Arr' is not assignable to type 'Arr extends readonly (infer InnerArr)[] ? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][D]> : Arr'.
55

66

@@ -28,7 +28,7 @@ flatArrayNoExcessiveStackDepth.ts(20,5): error TS2322: Type 'FlatArray<Arr, any>
2828
~
2929
!!! error TS2322: Type 'FlatArray<Arr, any>' is not assignable to type 'FlatArray<Arr, D>'.
3030
!!! error TS2322: Type 'Arr' is not assignable to type 'FlatArray<Arr, D>'.
31-
!!! error TS2322: Type 'Arr' is not assignable to type '(Arr extends readonly (infer InnerArr)[] ? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][D]> : Arr) & Arr'.
31+
!!! error TS2322: Type 'Arr' is not assignable to type 'Arr & (Arr extends readonly (infer InnerArr)[] ? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][D]> : Arr)'.
3232
!!! error TS2322: Type 'Arr' is not assignable to type 'Arr extends readonly (infer InnerArr)[] ? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][D]> : Arr'.
3333
}
3434

tests/cases/compiler/circularReferenceInReturnType.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,13 @@ const res2 = fn2()(() => res2);
1010

1111
declare function fn3<T>(): <T2>(cb: (arg: T2) => any) => (a: T) => void;
1212
const res3 = fn3()(() => res3);
13+
14+
// https://github.com/microsoft/TypeScript/issues/58616
15+
16+
function foo(arg: Parameters<typeof bar>[0]) {
17+
return arg;
18+
}
19+
20+
function bar(arg: string) {
21+
return foo(arg);
22+
}

0 commit comments

Comments
 (0)