Skip to content

Commit 5a45d5a

Browse files
committed
Reduce union and intersection targets when source is singleton type
1 parent d8b191a commit 5a45d5a

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

src/compiler/checker.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15500,15 +15500,10 @@ namespace ts {
1550015500
// of all their possible values.
1550115501
let matchingTypes: Type[] | undefined;
1550215502
for (const t of (<UnionOrIntersectionType>source).types) {
15503-
if (typeIdenticalToSomeType(t, (<UnionOrIntersectionType>target).types)) {
15504-
(matchingTypes || (matchingTypes = [])).push(t);
15505-
inferFromTypes(t, t);
15506-
}
15507-
else if (t.flags & (TypeFlags.NumberLiteral | TypeFlags.StringLiteral)) {
15508-
const b = getBaseTypeOfLiteralType(t);
15509-
if (typeIdenticalToSomeType(b, (<UnionOrIntersectionType>target).types)) {
15510-
(matchingTypes || (matchingTypes = [])).push(t, b);
15511-
}
15503+
const matched = findMatchedType(t, <UnionOrIntersectionType>target);
15504+
if (matched) {
15505+
(matchingTypes || (matchingTypes = [])).push(matched);
15506+
inferFromTypes(matched, matched);
1551215507
}
1551315508
}
1551415509
// Next, to improve the quality of inferences, reduce the source and target types by
@@ -15519,6 +15514,14 @@ namespace ts {
1551915514
target = removeTypesFromUnionOrIntersection(<UnionOrIntersectionType>target, matchingTypes);
1552015515
}
1552115516
}
15517+
else if (target.flags & TypeFlags.Union && !(target.flags & TypeFlags.EnumLiteral) || target.flags & TypeFlags.Intersection) {
15518+
const matched = findMatchedType(source, <UnionOrIntersectionType>target);
15519+
if (matched) {
15520+
inferFromTypes(matched, matched);
15521+
source = target.flags & TypeFlags.Union ? neverType : unknownType;
15522+
target = removeTypesFromUnionOrIntersection(<UnionOrIntersectionType>target, [matched]);
15523+
}
15524+
}
1552215525
else if (target.flags & (TypeFlags.IndexedAccess | TypeFlags.Substitution)) {
1552315526
target = getActualTypeVariable(target);
1552415527
}
@@ -15955,6 +15958,19 @@ namespace ts {
1595515958
return false;
1595615959
}
1595715960

15961+
function findMatchedType(type: Type, target: UnionOrIntersectionType) {
15962+
if (typeIdenticalToSomeType(type, target.types)) {
15963+
return type;
15964+
}
15965+
if (type.flags & (TypeFlags.NumberLiteral | TypeFlags.StringLiteral) && target.flags & TypeFlags.Union) {
15966+
const base = getBaseTypeOfLiteralType(type);
15967+
if (typeIdenticalToSomeType(base, target.types)) {
15968+
return base;
15969+
}
15970+
}
15971+
return undefined;
15972+
}
15973+
1595815974
/**
1595915975
* Return a new union or intersection type computed by removing a given set of types
1596015976
* from a given union or intersection type.

0 commit comments

Comments
 (0)