Skip to content

Commit f8b3ea7

Browse files
authored
Propagate errorType in getConditionalType (#53801)
1 parent 5897d7a commit f8b3ea7

6 files changed

+168
-11
lines changed

src/compiler/checker.ts

+9-7
Original file line numberDiff line numberDiff line change
@@ -17773,20 +17773,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1777317773
while (true) {
1777417774
if (tailCount === 1000) {
1777517775
error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
17776-
result = errorType;
17777-
break;
17776+
return errorType;
17777+
}
17778+
const checkType = instantiateType(getActualTypeVariable(root.checkType), mapper);
17779+
const extendsType = instantiateType(root.extendsType, mapper);
17780+
if (checkType === errorType || extendsType === errorType) {
17781+
return errorType;
17782+
}
17783+
if (checkType === wildcardType || extendsType === wildcardType) {
17784+
return wildcardType;
1777817785
}
1777917786
// When the check and extends types are simple tuple types of the same arity, we defer resolution of the
1778017787
// conditional type when any tuple elements are generic. This is such that non-distributable conditional
1778117788
// types can be written `[X] extends [Y] ? ...` and be deferred similarly to `X extends Y ? ...`.
1778217789
const checkTuples = isSimpleTupleType(root.node.checkType) && isSimpleTupleType(root.node.extendsType) &&
1778317790
length((root.node.checkType as TupleTypeNode).elements) === length((root.node.extendsType as TupleTypeNode).elements);
17784-
const checkType = instantiateType(getActualTypeVariable(root.checkType), mapper);
1778517791
const checkTypeDeferred = isDeferredType(checkType, checkTuples);
17786-
const extendsType = instantiateType(root.extendsType, mapper);
17787-
if (checkType === wildcardType || extendsType === wildcardType) {
17788-
return wildcardType;
17789-
}
1779017792
let combinedMapper: TypeMapper | undefined;
1779117793
if (root.inferTypeParameters) {
1779217794
// When we're looking at making an inference for an infer type, when we get its constraint, it'll automagically be

tests/baselines/reference/excessivelyLargeTupleSpread.errors.txt

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
tests/cases/compiler/excessivelyLargeTupleSpread.ts(6,10): error TS2589: Type instantiation is excessively deep and possibly infinite.
21
tests/cases/compiler/excessivelyLargeTupleSpread.ts(6,10): error TS2799: Type produces a tuple type that is too large to represent.
32
tests/cases/compiler/excessivelyLargeTupleSpread.ts(22,12): error TS2799: Type produces a tuple type that is too large to represent.
43
tests/cases/compiler/excessivelyLargeTupleSpread.ts(38,13): error TS2800: Expression produces a tuple type that is too large to represent.
54

65

7-
==== tests/cases/compiler/excessivelyLargeTupleSpread.ts (4 errors) ====
6+
==== tests/cases/compiler/excessivelyLargeTupleSpread.ts (3 errors) ====
87
// #41771
98

109
type BuildTuple<L extends number, T extends any[] = [any]> =
1110
T['length'] extends L ? T : BuildTuple<L, [...T, ...T]>;
1211

1312
type A = BuildTuple<3>
1413
~~~~~~~~~~~~~
15-
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
16-
~~~~~~~~~~~~~
1714
!!! error TS2799: Type produces a tuple type that is too large to represent.
1815

1916
type T0 = [any];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
tests/cases/compiler/recursiveConditionalCrash4.ts(7,16): error TS2503: Cannot find namespace 'StrIter'.
2+
tests/cases/compiler/recursiveConditionalCrash4.ts(8,5): error TS2503: Cannot find namespace 'StrIter'.
3+
tests/cases/compiler/recursiveConditionalCrash4.ts(9,25): error TS2304: Cannot find name 'Add'.
4+
tests/cases/compiler/recursiveConditionalCrash4.ts(9,37): error TS2503: Cannot find namespace 'StrIter'.
5+
tests/cases/compiler/recursiveConditionalCrash4.ts(10,7): error TS2589: Type instantiation is excessively deep and possibly infinite.
6+
tests/cases/compiler/recursiveConditionalCrash4.ts(10,31): error TS2503: Cannot find namespace 'StrIter'.
7+
tests/cases/compiler/recursiveConditionalCrash4.ts(16,7): error TS2589: Type instantiation is excessively deep and possibly infinite.
8+
9+
10+
==== tests/cases/compiler/recursiveConditionalCrash4.ts (7 errors) ====
11+
// Repros from #53783
12+
13+
type LengthDown<
14+
Str extends string,
15+
Length extends number | bigint,
16+
It
17+
> = It extends StrIter.Iterator
18+
~~~~~~~
19+
!!! error TS2503: Cannot find namespace 'StrIter'.
20+
? StrIter.CutAt<Str, It> extends `${infer $Rest}`
21+
~~~~~~~
22+
!!! error TS2503: Cannot find namespace 'StrIter'.
23+
? LengthDown<$Rest, Add<Length, StrIter.Value<It>>, It>
24+
~~~
25+
!!! error TS2304: Cannot find name 'Add'.
26+
~~~~~~~
27+
!!! error TS2503: Cannot find namespace 'StrIter'.
28+
: LengthDown<Str, Length, StrIter.Prev<It>>
29+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
30+
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
31+
~~~~~~~
32+
!!! error TS2503: Cannot find namespace 'StrIter'.
33+
: Length;
34+
35+
type Foo<T> = T extends unknown
36+
? unknown extends `${infer $Rest}`
37+
? Foo<T>
38+
: Foo<unknown>
39+
~~~~~~~~~~~~
40+
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
41+
: unknown;
42+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
=== tests/cases/compiler/recursiveConditionalCrash4.ts ===
2+
// Repros from #53783
3+
4+
type LengthDown<
5+
>LengthDown : Symbol(LengthDown, Decl(recursiveConditionalCrash4.ts, 0, 0))
6+
7+
Str extends string,
8+
>Str : Symbol(Str, Decl(recursiveConditionalCrash4.ts, 2, 16))
9+
10+
Length extends number | bigint,
11+
>Length : Symbol(Length, Decl(recursiveConditionalCrash4.ts, 3, 21))
12+
13+
It
14+
>It : Symbol(It, Decl(recursiveConditionalCrash4.ts, 4, 33))
15+
16+
> = It extends StrIter.Iterator
17+
>It : Symbol(It, Decl(recursiveConditionalCrash4.ts, 4, 33))
18+
>StrIter : Symbol(StrIter)
19+
>Iterator : Symbol(StrIter.Iterator)
20+
21+
? StrIter.CutAt<Str, It> extends `${infer $Rest}`
22+
>StrIter : Symbol(StrIter)
23+
>CutAt : Symbol(StrIter.CutAt)
24+
>Str : Symbol(Str, Decl(recursiveConditionalCrash4.ts, 2, 16))
25+
>It : Symbol(It, Decl(recursiveConditionalCrash4.ts, 4, 33))
26+
>$Rest : Symbol($Rest, Decl(recursiveConditionalCrash4.ts, 7, 43))
27+
28+
? LengthDown<$Rest, Add<Length, StrIter.Value<It>>, It>
29+
>LengthDown : Symbol(LengthDown, Decl(recursiveConditionalCrash4.ts, 0, 0))
30+
>$Rest : Symbol($Rest, Decl(recursiveConditionalCrash4.ts, 7, 43))
31+
>Add : Symbol(Add)
32+
>Length : Symbol(Length, Decl(recursiveConditionalCrash4.ts, 3, 21))
33+
>StrIter : Symbol(StrIter)
34+
>Value : Symbol(StrIter.Value)
35+
>It : Symbol(It, Decl(recursiveConditionalCrash4.ts, 4, 33))
36+
>It : Symbol(It, Decl(recursiveConditionalCrash4.ts, 4, 33))
37+
38+
: LengthDown<Str, Length, StrIter.Prev<It>>
39+
>LengthDown : Symbol(LengthDown, Decl(recursiveConditionalCrash4.ts, 0, 0))
40+
>Str : Symbol(Str, Decl(recursiveConditionalCrash4.ts, 2, 16))
41+
>Length : Symbol(Length, Decl(recursiveConditionalCrash4.ts, 3, 21))
42+
>StrIter : Symbol(StrIter)
43+
>Prev : Symbol(StrIter.Prev)
44+
>It : Symbol(It, Decl(recursiveConditionalCrash4.ts, 4, 33))
45+
46+
: Length;
47+
>Length : Symbol(Length, Decl(recursiveConditionalCrash4.ts, 3, 21))
48+
49+
type Foo<T> = T extends unknown
50+
>Foo : Symbol(Foo, Decl(recursiveConditionalCrash4.ts, 10, 11))
51+
>T : Symbol(T, Decl(recursiveConditionalCrash4.ts, 12, 9))
52+
>T : Symbol(T, Decl(recursiveConditionalCrash4.ts, 12, 9))
53+
54+
? unknown extends `${infer $Rest}`
55+
>$Rest : Symbol($Rest, Decl(recursiveConditionalCrash4.ts, 13, 28))
56+
57+
? Foo<T>
58+
>Foo : Symbol(Foo, Decl(recursiveConditionalCrash4.ts, 10, 11))
59+
>T : Symbol(T, Decl(recursiveConditionalCrash4.ts, 12, 9))
60+
61+
: Foo<unknown>
62+
>Foo : Symbol(Foo, Decl(recursiveConditionalCrash4.ts, 10, 11))
63+
64+
: unknown;
65+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
=== tests/cases/compiler/recursiveConditionalCrash4.ts ===
2+
// Repros from #53783
3+
4+
type LengthDown<
5+
>LengthDown : LengthDown<Str, Length, It>
6+
7+
Str extends string,
8+
Length extends number | bigint,
9+
It
10+
> = It extends StrIter.Iterator
11+
>StrIter : any
12+
13+
? StrIter.CutAt<Str, It> extends `${infer $Rest}`
14+
>StrIter : any
15+
16+
? LengthDown<$Rest, Add<Length, StrIter.Value<It>>, It>
17+
>StrIter : any
18+
19+
: LengthDown<Str, Length, StrIter.Prev<It>>
20+
>StrIter : any
21+
22+
: Length;
23+
24+
type Foo<T> = T extends unknown
25+
>Foo : Foo<T>
26+
27+
? unknown extends `${infer $Rest}`
28+
? Foo<T>
29+
: Foo<unknown>
30+
: unknown;
31+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// Repros from #53783
5+
6+
type LengthDown<
7+
Str extends string,
8+
Length extends number | bigint,
9+
It
10+
> = It extends StrIter.Iterator
11+
? StrIter.CutAt<Str, It> extends `${infer $Rest}`
12+
? LengthDown<$Rest, Add<Length, StrIter.Value<It>>, It>
13+
: LengthDown<Str, Length, StrIter.Prev<It>>
14+
: Length;
15+
16+
type Foo<T> = T extends unknown
17+
? unknown extends `${infer $Rest}`
18+
? Foo<T>
19+
: Foo<unknown>
20+
: unknown;

0 commit comments

Comments
 (0)