@@ -12767,26 +12767,26 @@ namespace ts {
12767
12767
// We attempt to resolve the conditional type only when the check and extends types are non-generic
12768
12768
if (!checkTypeInstantiable && !isGenericObjectType(inferredExtendsType) && !isGenericIndexType(inferredExtendsType)) {
12769
12769
if (inferredExtendsType.flags & TypeFlags.AnyOrUnknown) {
12770
- return instantiateType (root.trueType, combinedMapper || mapper);
12770
+ return instantiateTypeWithoutDepthIncrease (root.trueType, combinedMapper || mapper);
12771
12771
}
12772
12772
// Return union of trueType and falseType for 'any' since it matches anything
12773
12773
if (checkType.flags & TypeFlags.Any) {
12774
- return getUnionType([instantiateType (root.trueType, combinedMapper || mapper), instantiateType (root.falseType, mapper)]);
12774
+ return getUnionType([instantiateTypeWithoutDepthIncrease (root.trueType, combinedMapper || mapper), instantiateTypeWithoutDepthIncrease (root.falseType, mapper)]);
12775
12775
}
12776
12776
// Return falseType for a definitely false extends check. We check an instantiations of the two
12777
12777
// types with type parameters mapped to the wildcard type, the most permissive instantiations
12778
12778
// possible (the wildcard type is assignable to and from all types). If those are not related,
12779
12779
// then no instantiations will be and we can just return the false branch type.
12780
12780
if (!isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType))) {
12781
- return instantiateType (root.falseType, mapper);
12781
+ return instantiateTypeWithoutDepthIncrease (root.falseType, mapper);
12782
12782
}
12783
12783
// Return trueType for a definitely true extends check. We check instantiations of the two
12784
12784
// types with type parameters mapped to their restrictive form, i.e. a form of the type parameter
12785
12785
// that has no constraint. This ensures that, for example, the type
12786
12786
// type Foo<T extends { x: any }> = T extends { x: string } ? string : number
12787
12787
// doesn't immediately resolve to 'string' instead of being deferred.
12788
12788
if (isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) {
12789
- return instantiateType (root.trueType, combinedMapper || mapper);
12789
+ return instantiateTypeWithoutDepthIncrease (root.trueType, combinedMapper || mapper);
12790
12790
}
12791
12791
}
12792
12792
// Return a deferred type for a check that is neither definitely true nor definitely false
@@ -13771,6 +13771,17 @@ namespace ts {
13771
13771
return result;
13772
13772
}
13773
13773
13774
+ /**
13775
+ * This can be used to avoid the penalty on instantiation depth for types which result from immediate
13776
+ * simplification. It essentially removes the depth increase done in `instantiateType`.
13777
+ */
13778
+ function instantiateTypeWithoutDepthIncrease(type: Type, mapper: TypeMapper | undefined) {
13779
+ instantiationDepth--;
13780
+ const result = instantiateType(type, mapper);
13781
+ instantiationDepth++;
13782
+ return result;
13783
+ }
13784
+
13774
13785
function instantiateTypeWorker(type: Type, mapper: TypeMapper): Type {
13775
13786
const flags = type.flags;
13776
13787
if (flags & TypeFlags.TypeParameter) {
0 commit comments