@@ -17343,16 +17343,45 @@ namespace ts {
1734317343 // Distributive conditional types are distributed over union types. For example, when the
1734417344 // distributive conditional type T extends U ? X : Y is instantiated with A | B for T, the
1734517345 // result is (A extends U ? X : Y) | (B extends U ? X : Y).
17346- result = distributionType && checkType !== distributionType && distributionType.flags & (TypeFlags.Union | TypeFlags.Never) ?
17347- mapTypeWithAlias(getReducedType(distributionType), t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper)), aliasSymbol, aliasTypeArguments) :
17348- getConditionalType(root, newMapper, aliasSymbol, aliasTypeArguments);
17346+ result = distributionType && checkType !== distributionType && distributionType.flags & (TypeFlags.Union | TypeFlags.Never)
17347+ ? root.isDistributive && !isDistributionDependent(root) && !containsInferTypeNode(root.node)
17348+ ? getConditionalTypeForSimpleDistributionType(getReducedType(distributionType), (t) => getConditionalType(root, prependTypeMapping(checkType, t, newMapper)), aliasSymbol, aliasTypeArguments)
17349+ : mapTypeWithAlias(getReducedType(distributionType), (t) => getConditionalType(root, prependTypeMapping(checkType, t, newMapper)), aliasSymbol, aliasTypeArguments)
17350+ : getConditionalType(root, newMapper, aliasSymbol, aliasTypeArguments);
1734917351 root.instantiations!.set(id, result);
1735017352 }
1735117353 return result;
1735217354 }
1735317355 return type;
1735417356 }
1735517357
17358+ // For types like A extends B ? C : D, if the check-type (A) appears in neither branch and the extends type (B) has no infer positions,
17359+ // the output type will be combinations of C and D.
17360+ function getConditionalTypeForSimpleDistributionType(type: Type, mapper: (t: Type) => Type, aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined): Type {
17361+ if (!(type.flags & TypeFlags.Union && aliasSymbol)) {
17362+ return mapType(type, mapper);
17363+ }
17364+ let firstMappedType: Type | undefined;
17365+ for(const t of (type as UnionType).types) {
17366+ const mapped = mapper(t);
17367+ if (mapped.flags & TypeFlags.AnyOrUnknown) {
17368+ return mapped;
17369+ }
17370+ else if (!firstMappedType) {
17371+ firstMappedType = mapped;
17372+ }
17373+ else if (firstMappedType !== mapped) {
17374+ return getUnionType([firstMappedType, mapped], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
17375+ }
17376+ }
17377+ Debug.assertIsDefined(firstMappedType);
17378+ return firstMappedType;
17379+ }
17380+
17381+ function containsInferTypeNode(node: Node) {
17382+ return isInferTypeNode(node) || forEachChildRecursively(node, isInferTypeNode);
17383+ }
17384+
1735617385 function instantiateType(type: Type, mapper: TypeMapper | undefined): Type;
1735717386 function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined;
1735817387 function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined {
0 commit comments