@@ -12767,38 +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
- instantiationDepth--;
12771
- const result = instantiateType(root.trueType, combinedMapper || mapper);
12772
- instantiationDepth++;
12773
- return result;
12770
+ return instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper);
12774
12771
}
12775
12772
// Return union of trueType and falseType for 'any' since it matches anything
12776
12773
if (checkType.flags & TypeFlags.Any) {
12777
- instantiationDepth--;
12778
- const result = getUnionType([instantiateType(root.trueType, combinedMapper || mapper), instantiateType(root.falseType, mapper)]);
12779
- instantiationDepth++;
12780
- return result;
12774
+ return getUnionType([instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper), instantiateTypeWithoutDepthIncrease(root.falseType, mapper)]);
12781
12775
}
12782
12776
// Return falseType for a definitely false extends check. We check an instantiations of the two
12783
12777
// types with type parameters mapped to the wildcard type, the most permissive instantiations
12784
12778
// possible (the wildcard type is assignable to and from all types). If those are not related,
12785
12779
// then no instantiations will be and we can just return the false branch type.
12786
12780
if (!isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType))) {
12787
- instantiationDepth--;
12788
- const result = instantiateType(root.falseType, mapper);
12789
- instantiationDepth++;
12790
- return result;
12781
+ return instantiateTypeWithoutDepthIncrease(root.falseType, mapper);
12791
12782
}
12792
12783
// Return trueType for a definitely true extends check. We check instantiations of the two
12793
12784
// types with type parameters mapped to their restrictive form, i.e. a form of the type parameter
12794
12785
// that has no constraint. This ensures that, for example, the type
12795
12786
// type Foo<T extends { x: any }> = T extends { x: string } ? string : number
12796
12787
// doesn't immediately resolve to 'string' instead of being deferred.
12797
12788
if (isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) {
12798
- instantiationDepth--;
12799
- const result = instantiateType(root.trueType, combinedMapper || mapper);
12800
- instantiationDepth++;
12801
- return result;
12789
+ return instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper);
12802
12790
}
12803
12791
}
12804
12792
// Return a deferred type for a check that is neither definitely true nor definitely false
@@ -13783,6 +13771,17 @@ namespace ts {
13783
13771
return result;
13784
13772
}
13785
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
+
13786
13785
function instantiateTypeWorker(type: Type, mapper: TypeMapper): Type {
13787
13786
const flags = type.flags;
13788
13787
if (flags & TypeFlags.TypeParameter) {
0 commit comments