Only resolve source return type when actually needed during inference (#58650)

This commit is contained in:
Anders Hejlsberg
2024-05-28 08:10:06 -07:00
committed by GitHub
parent af3a61fe44
commit 1d026a9f69
7 changed files with 90 additions and 21 deletions
+9 -5
View File
@@ -25172,13 +25172,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function applyToReturnTypes(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) {
const sourceTypePredicate = getTypePredicateOfSignature(source);
const targetTypePredicate = getTypePredicateOfSignature(target);
if (sourceTypePredicate && targetTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) {
callback(sourceTypePredicate.type, targetTypePredicate.type);
if (targetTypePredicate) {
const sourceTypePredicate = getTypePredicateOfSignature(source);
if (sourceTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) {
callback(sourceTypePredicate.type, targetTypePredicate.type);
return;
}
}
else {
callback(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
const targetReturnType = getReturnTypeOfSignature(target);
if (couldContainTypeVariables(targetReturnType)) {
callback(getReturnTypeOfSignature(source), targetReturnType);
}
}
@@ -1,10 +1,8 @@
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.
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.
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.
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.
==== circularReferenceInReturnType.ts (4 errors) ====
==== circularReferenceInReturnType.ts (2 errors) ====
// inference fails for res1 and res2, but ideally should not
declare function fn1<T>(cb: () => T): string;
const res1 = fn1(() => res1);
@@ -18,8 +16,14 @@ circularReferenceInReturnType.ts(9,20): error TS7024: Function implicitly has re
declare function fn3<T>(): <T2>(cb: (arg: T2) => any) => (a: T) => void;
const res3 = fn3()(() => res3);
~~~~
!!! 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.
~~~~~~~~~~
!!! 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.
// https://github.com/microsoft/TypeScript/issues/58616
function foo(arg: Parameters<typeof bar>[0]) {
return arg;
}
function bar(arg: string) {
return foo(arg);
}
@@ -40,3 +40,24 @@ const res3 = fn3()(() => res3);
>fn3 : Symbol(fn3, Decl(circularReferenceInReturnType.ts, 5, 31))
>res3 : Symbol(res3, Decl(circularReferenceInReturnType.ts, 8, 5))
// https://github.com/microsoft/TypeScript/issues/58616
function foo(arg: Parameters<typeof bar>[0]) {
>foo : Symbol(foo, Decl(circularReferenceInReturnType.ts, 8, 31))
>arg : Symbol(arg, Decl(circularReferenceInReturnType.ts, 12, 13))
>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --))
>bar : Symbol(bar, Decl(circularReferenceInReturnType.ts, 14, 1))
return arg;
>arg : Symbol(arg, Decl(circularReferenceInReturnType.ts, 12, 13))
}
function bar(arg: string) {
>bar : Symbol(bar, Decl(circularReferenceInReturnType.ts, 14, 1))
>arg : Symbol(arg, Decl(circularReferenceInReturnType.ts, 16, 13))
return foo(arg);
>foo : Symbol(foo, Decl(circularReferenceInReturnType.ts, 8, 31))
>arg : Symbol(arg, Decl(circularReferenceInReturnType.ts, 16, 13))
}
@@ -53,16 +53,46 @@ declare function fn3<T>(): <T2>(cb: (arg: T2) => any) => (a: T) => void;
> : ^
const res3 = fn3()(() => res3);
>res3 : any
> : ^^^
>res3 : (a: unknown) => void
> : ^ ^^^^^^^^^^^^^^
>fn3()(() => res3) : (a: unknown) => void
> : ^ ^^^^^^^^^^^^^^
>fn3() : <T2>(cb: (arg: T2) => any) => (a: unknown) => void
> : ^^^^^ ^^^ ^^^^^^^^^ ^^^^^ ^^^^^^^
>fn3 : <T>() => <T2>(cb: (arg: T2) => any) => (a: T) => void
> : ^ ^^^^^^^
>() => res3 : () => any
> : ^^^^^^^^^
>res3 : any
> : ^^^
>() => res3 : () => (a: unknown) => void
> : ^^^^^^^ ^^^^^^^^^^^^^^
>res3 : (a: unknown) => void
> : ^ ^^^^^^^^^^^^^^
// https://github.com/microsoft/TypeScript/issues/58616
function foo(arg: Parameters<typeof bar>[0]) {
>foo : (arg: Parameters<typeof bar>[0]) => string
> : ^ ^^ ^^^^^^^^^^^
>arg : string
> : ^^^^^^
>bar : (arg: string) => string
> : ^ ^^ ^^^^^^^^^^^
return arg;
>arg : string
> : ^^^^^^
}
function bar(arg: string) {
>bar : (arg: string) => string
> : ^ ^^ ^^^^^^^^^^^
>arg : string
> : ^^^^^^
return foo(arg);
>foo(arg) : string
> : ^^^^^^
>foo : (arg: Parameters<typeof bar>[0]) => string
> : ^ ^^ ^^^^^^^^^^^
>arg : string
> : ^^^^^^
}
@@ -3,7 +3,7 @@
=== Performance Stats ===
Assignability cache: 10,000
Type Count: 50,000
Instantiation count: 250,000
Instantiation count: 100,000
Symbol count: 100,000
=== complex.ts ===
@@ -1,6 +1,6 @@
flatArrayNoExcessiveStackDepth.ts(20,5): error TS2322: Type 'FlatArray<Arr, any>' is not assignable to type 'FlatArray<Arr, D>'.
Type 'Arr' is not assignable to type 'FlatArray<Arr, D>'.
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'.
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)'.
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'.
@@ -28,7 +28,7 @@ flatArrayNoExcessiveStackDepth.ts(20,5): error TS2322: Type 'FlatArray<Arr, any>
~
!!! error TS2322: Type 'FlatArray<Arr, any>' is not assignable to type 'FlatArray<Arr, D>'.
!!! error TS2322: Type 'Arr' is not assignable to type 'FlatArray<Arr, D>'.
!!! 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'.
!!! 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)'.
!!! 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'.
}
@@ -10,3 +10,13 @@ const res2 = fn2()(() => res2);
declare function fn3<T>(): <T2>(cb: (arg: T2) => any) => (a: T) => void;
const res3 = fn3()(() => res3);
// https://github.com/microsoft/TypeScript/issues/58616
function foo(arg: Parameters<typeof bar>[0]) {
return arg;
}
function bar(arg: string) {
return foo(arg);
}