@@ -12707,38 +12707,26 @@ namespace ts {
12707
12707
// We attempt to resolve the conditional type only when the check and extends types are non-generic
12708
12708
if (!checkTypeInstantiable && !maybeTypeOfKind(inferredExtendsType, TypeFlags.Instantiable | TypeFlags.GenericMappedType)) {
12709
12709
if (inferredExtendsType.flags & TypeFlags.AnyOrUnknown) {
12710
- instantiationDepth--;
12711
- const result = instantiateType(root.trueType, combinedMapper || mapper);
12712
- instantiationDepth++;
12713
- return result;
12710
+ return instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper);
12714
12711
}
12715
12712
// Return union of trueType and falseType for 'any' since it matches anything
12716
12713
if (checkType.flags & TypeFlags.Any) {
12717
- instantiationDepth--;
12718
- const result = getUnionType([instantiateType(root.trueType, combinedMapper || mapper), instantiateType(root.falseType, mapper)]);
12719
- instantiationDepth++;
12720
- return result;
12714
+ return getUnionType([instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper), instantiateTypeWithoutDepthIncrease(root.falseType, mapper)]);
12721
12715
}
12722
12716
// Return falseType for a definitely false extends check. We check an instantiations of the two
12723
12717
// types with type parameters mapped to the wildcard type, the most permissive instantiations
12724
12718
// possible (the wildcard type is assignable to and from all types). If those are not related,
12725
12719
// then no instantiations will be and we can just return the false branch type.
12726
12720
if (!isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType))) {
12727
- instantiationDepth--;
12728
- const result = instantiateType(root.falseType, mapper);
12729
- instantiationDepth++;
12730
- return result;
12721
+ return instantiateTypeWithoutDepthIncrease(root.falseType, mapper);
12731
12722
}
12732
12723
// Return trueType for a definitely true extends check. We check instantiations of the two
12733
12724
// types with type parameters mapped to their restrictive form, i.e. a form of the type parameter
12734
12725
// that has no constraint. This ensures that, for example, the type
12735
12726
// type Foo<T extends { x: any }> = T extends { x: string } ? string : number
12736
12727
// doesn't immediately resolve to 'string' instead of being deferred.
12737
12728
if (isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) {
12738
- instantiationDepth--;
12739
- const result = instantiateType(root.trueType, combinedMapper || mapper);
12740
- instantiationDepth++;
12741
- return result;
12729
+ return instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper);
12742
12730
}
12743
12731
}
12744
12732
// Return a deferred type for a check that is neither definitely true nor definitely false
@@ -13715,6 +13703,17 @@ namespace ts {
13715
13703
return result;
13716
13704
}
13717
13705
13706
+ /**
13707
+ * This can be used to avoid the penalty on instantiation depth for types which result from immediate
13708
+ * simplification. It essentially removes the depth increase done in `instantiateType`.
13709
+ */
13710
+ function instantiateTypeWithoutDepthIncrease(type: Type, mapper: TypeMapper | undefined) {
13711
+ instantiationDepth--;
13712
+ const result = instantiateType(type, mapper);
13713
+ instantiationDepth++;
13714
+ return result;
13715
+ }
13716
+
13718
13717
function instantiateTypeWorker(type: Type, mapper: TypeMapper): Type {
13719
13718
const flags = type.flags;
13720
13719
if (flags & TypeFlags.TypeParameter) {
0 commit comments