Skip to content

Commit e2bf8b4

Browse files
authored
Fixed distributive conditional types with never intersections (#57345)
1 parent c5db0ac commit e2bf8b4

4 files changed

+70
-2
lines changed

src/compiler/checker.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -19877,12 +19877,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1987719877
if (!result) {
1987819878
const newMapper = createTypeMapper(root.outerTypeParameters, typeArguments);
1987919879
const checkType = root.checkType;
19880-
const distributionType = root.isDistributive ? getMappedType(checkType, newMapper) : undefined;
19880+
const distributionType = root.isDistributive ? getReducedType(getMappedType(checkType, newMapper)) : undefined;
1988119881
// Distributive conditional types are distributed over union types. For example, when the
1988219882
// distributive conditional type T extends U ? X : Y is instantiated with A | B for T, the
1988319883
// result is (A extends U ? X : Y) | (B extends U ? X : Y).
1988419884
result = distributionType && checkType !== distributionType && distributionType.flags & (TypeFlags.Union | TypeFlags.Never) ?
19885-
mapTypeWithAlias(getReducedType(distributionType), t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper), forConstraint), aliasSymbol, aliasTypeArguments) :
19885+
mapTypeWithAlias(distributionType, t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper), forConstraint), aliasSymbol, aliasTypeArguments) :
1988619886
getConditionalType(root, newMapper, forConstraint, aliasSymbol, aliasTypeArguments);
1988719887
root.instantiations!.set(id, result);
1988819888
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//// [tests/cases/compiler/distributiveConditionalTypeNeverIntersection1.ts] ////
2+
3+
=== distributiveConditionalTypeNeverIntersection1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/57343
5+
6+
type IsNumber<T> = T extends number ? true : false;
7+
>IsNumber : Symbol(IsNumber, Decl(distributiveConditionalTypeNeverIntersection1.ts, 0, 0))
8+
>T : Symbol(T, Decl(distributiveConditionalTypeNeverIntersection1.ts, 2, 14))
9+
>T : Symbol(T, Decl(distributiveConditionalTypeNeverIntersection1.ts, 2, 14))
10+
11+
type Conflicted = { x: true } & { x: false };
12+
>Conflicted : Symbol(Conflicted, Decl(distributiveConditionalTypeNeverIntersection1.ts, 2, 51))
13+
>x : Symbol(x, Decl(distributiveConditionalTypeNeverIntersection1.ts, 4, 19))
14+
>x : Symbol(x, Decl(distributiveConditionalTypeNeverIntersection1.ts, 4, 33))
15+
16+
type Ex1 = IsNumber<Conflicted>; // never
17+
>Ex1 : Symbol(Ex1, Decl(distributiveConditionalTypeNeverIntersection1.ts, 4, 45))
18+
>IsNumber : Symbol(IsNumber, Decl(distributiveConditionalTypeNeverIntersection1.ts, 0, 0))
19+
>Conflicted : Symbol(Conflicted, Decl(distributiveConditionalTypeNeverIntersection1.ts, 2, 51))
20+
21+
type Ex2 = IsNumber<"OEEE" | Conflicted>; // false
22+
>Ex2 : Symbol(Ex2, Decl(distributiveConditionalTypeNeverIntersection1.ts, 6, 32))
23+
>IsNumber : Symbol(IsNumber, Decl(distributiveConditionalTypeNeverIntersection1.ts, 0, 0))
24+
>Conflicted : Symbol(Conflicted, Decl(distributiveConditionalTypeNeverIntersection1.ts, 2, 51))
25+
26+
type Ex3 = IsNumber<1 | Conflicted>; // true
27+
>Ex3 : Symbol(Ex3, Decl(distributiveConditionalTypeNeverIntersection1.ts, 7, 41))
28+
>IsNumber : Symbol(IsNumber, Decl(distributiveConditionalTypeNeverIntersection1.ts, 0, 0))
29+
>Conflicted : Symbol(Conflicted, Decl(distributiveConditionalTypeNeverIntersection1.ts, 2, 51))
30+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//// [tests/cases/compiler/distributiveConditionalTypeNeverIntersection1.ts] ////
2+
3+
=== distributiveConditionalTypeNeverIntersection1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/57343
5+
6+
type IsNumber<T> = T extends number ? true : false;
7+
>IsNumber : IsNumber<T>
8+
>true : true
9+
>false : false
10+
11+
type Conflicted = { x: true } & { x: false };
12+
>Conflicted : never
13+
>x : true
14+
>true : true
15+
>x : false
16+
>false : false
17+
18+
type Ex1 = IsNumber<Conflicted>; // never
19+
>Ex1 : never
20+
21+
type Ex2 = IsNumber<"OEEE" | Conflicted>; // false
22+
>Ex2 : false
23+
24+
type Ex3 = IsNumber<1 | Conflicted>; // true
25+
>Ex3 : true
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/57343
5+
6+
type IsNumber<T> = T extends number ? true : false;
7+
8+
type Conflicted = { x: true } & { x: false };
9+
10+
type Ex1 = IsNumber<Conflicted>; // never
11+
type Ex2 = IsNumber<"OEEE" | Conflicted>; // false
12+
type Ex3 = IsNumber<1 | Conflicted>; // true

0 commit comments

Comments
 (0)