@@ -14567,16 +14567,33 @@ namespace ts {
1456714567 return type;
1456814568 }
1456914569
14570+ function isTypicalNondistributiveConditional(root: ConditionalRoot) {
14571+ return !root.isDistributive
14572+ && root.node.checkType.kind === SyntaxKind.TupleType
14573+ && length((root.node.checkType as TupleTypeNode).elements) === 1
14574+ && root.node.extendsType.kind === SyntaxKind.TupleType
14575+ && length((root.node.extendsType as TupleTypeNode).elements) === 1;
14576+ }
14577+
14578+ /**
14579+ * We syntactually check for common nondistributive conditional shapes and unwrap them into
14580+ * the intended comparison - we do this so we can check if the unwrapped types are generic or
14581+ * not and appropriately defer condition calculation
14582+ */
14583+ function unwrapNondistributiveConditionalTuple(root: ConditionalRoot, type: Type) {
14584+ return isTypicalNondistributiveConditional(root) && isTupleType(type) ? getTypeArguments(type)[0] : type;
14585+ }
14586+
1457014587 function getConditionalType(root: ConditionalRoot, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
1457114588 let result;
1457214589 let extraTypes: Type[] | undefined;
1457314590 // We loop here for an immediately nested conditional type in the false position, effectively treating
1457414591 // types of the form 'A extends B ? X : C extends D ? Y : E extends F ? Z : ...' as a single construct for
1457514592 // purposes of resolution. This means such types aren't subject to the instatiation depth limiter.
1457614593 while (true) {
14577- const checkType = instantiateType(root.checkType, mapper);
14594+ const checkType = instantiateType(unwrapNondistributiveConditionalTuple( root, root .checkType) , mapper);
1457814595 const checkTypeInstantiable = isGenericObjectType(checkType) || isGenericIndexType(checkType);
14579- const extendsType = instantiateType(root.extendsType, mapper);
14596+ const extendsType = instantiateType(unwrapNondistributiveConditionalTuple( root, root .extendsType) , mapper);
1458014597 if (checkType === wildcardType || extendsType === wildcardType) {
1458114598 return wildcardType;
1458214599 }
@@ -14599,9 +14616,9 @@ namespace ts {
1459914616 // types with type parameters mapped to the wildcard type, the most permissive instantiations
1460014617 // possible (the wildcard type is assignable to and from all types). If those are not related,
1460114618 // then no instantiations will be and we can just return the false branch type.
14602- if (!(inferredExtendsType.flags & TypeFlags.AnyOrUnknown) && (checkType.flags & TypeFlags.Any || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) {
14619+ if (!(inferredExtendsType.flags & TypeFlags.AnyOrUnknown) && (( checkType.flags & TypeFlags.Any && root.isDistributive) || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) {
1460314620 // Return union of trueType and falseType for 'any' since it matches anything
14604- if (checkType.flags & TypeFlags.Any) {
14621+ if (checkType.flags & TypeFlags.Any && root.isDistributive ) {
1460514622 (extraTypes || (extraTypes = [])).push(instantiateType(getTypeFromTypeNode(root.node.trueType), combinedMapper || mapper));
1460614623 }
1460714624 // If falseType is an immediately nested conditional type that isn't distributive or has an
@@ -14630,8 +14647,8 @@ namespace ts {
1463014647 // Return a deferred type for a check that is neither definitely true nor definitely false
1463114648 result = <ConditionalType>createType(TypeFlags.Conditional);
1463214649 result.root = root;
14633- result.checkType = checkType;
14634- result.extendsType = extendsType;
14650+ result.checkType = instantiateType(root. checkType, mapper) ;
14651+ result.extendsType = instantiateType(root. extendsType, mapper) ;
1463514652 result.mapper = mapper;
1463614653 result.combinedMapper = combinedMapper;
1463714654 result.aliasSymbol = aliasSymbol || root.aliasSymbol;
0 commit comments