Skip to content

Commit b81c98b

Browse files
committed
Bail on unwrapping conditional constraints on the source side when the source conditional is already known to be spooling out of control
1 parent 363e392 commit b81c98b

File tree

2 files changed

+15
-11
lines changed

2 files changed

+15
-11
lines changed

src/compiler/checker.ts

+13-7
Original file line numberDiff line numberDiff line change
@@ -18390,13 +18390,19 @@ namespace ts {
1839018390
}
1839118391
}
1839218392
}
18393-
// conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O`
18394-
// when `O` is a conditional (`never` is trivially aissgnable to `O`, as is `O`!).
18395-
const defaultConstraint = getDefaultConstraintOfConditionalType(<ConditionalType>source);
18396-
if (defaultConstraint) {
18397-
if (result = isRelatedTo(defaultConstraint, target, reportErrors)) {
18398-
resetErrorInfo(saveErrorInfo);
18399-
return result;
18393+
18394+
18395+
// We'll repeatedly decompose source side conditionals if they're recursive - check if we've already recured on the constraint a lot and, if so, bail
18396+
// on the comparison.
18397+
if (!isDeeplyNestedType(source, sourceStack, sourceDepth)) {
18398+
// conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O`
18399+
// when `O` is a conditional (`never` is trivially aissgnable to `O`, as is `O`!).
18400+
const defaultConstraint = getDefaultConstraintOfConditionalType(<ConditionalType>source);
18401+
if (defaultConstraint) {
18402+
if (result = isRelatedTo(defaultConstraint, target, reportErrors)) {
18403+
resetErrorInfo(saveErrorInfo);
18404+
return result;
18405+
}
1840018406
}
1840118407
}
1840218408
}

tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt

+2-4
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcre
88
Type 'ReturnType<T[number]>' is not assignable to type 'A'.
99
Type 'unknown' is not assignable to type 'A'.
1010
Type 'ReturnType<FunctionsObj<T>[number]>' is not assignable to type 'A'.
11-
Type 'unknown' is not assignable to type 'A'.
12-
Property 'x' is missing in type '{}' but required in type 'A'.
11+
Property 'x' is missing in type '{}' but required in type 'A'.
1312

1413

1514
==== tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts (1 errors) ====
@@ -37,8 +36,7 @@ tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcre
3736
!!! error TS2322: Type 'ReturnType<T[number]>' is not assignable to type 'A'.
3837
!!! error TS2322: Type 'unknown' is not assignable to type 'A'.
3938
!!! error TS2322: Type 'ReturnType<FunctionsObj<T>[number]>' is not assignable to type 'A'.
40-
!!! error TS2322: Type 'unknown' is not assignable to type 'A'.
41-
!!! error TS2322: Property 'x' is missing in type '{}' but required in type 'A'.
39+
!!! error TS2322: Property 'x' is missing in type '{}' but required in type 'A'.
4240
!!! related TS2728 tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts:1:15: 'x' is declared here.
4341
}
4442

0 commit comments

Comments
 (0)