Skip to content

Commit 2d15222

Browse files
committed
Add fast path for unions of unions
1 parent ba6f527 commit 2d15222

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

src/compiler/checker.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21409,13 +21409,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2140921409
// we need to deconstruct unions before intersections (because unions are always at the top),
2141021410
// and we need to handle "each" relations before "some" relations for the same kind of type.
2141121411
if (source.flags & TypeFlags.Union) {
21412-
// Intersections of union types are normalized into unions of intersection types, and such normalized
21413-
// unions can get very large and expensive to relate. The following fast path checks if the source union
21414-
// originated in an intersection. If so, and if that intersection contains the target type, then we know
21415-
// the result to be true (for any two types A and B, A & B is related to both A and B).
21416-
const origin = (source as UnionType).origin;
21417-
if (origin && origin.flags & TypeFlags.Intersection && contains((origin as IntersectionType).types, target)) {
21418-
return Ternary.True;
21412+
if (target.flags & TypeFlags.Union) {
21413+
// Intersections of union types are normalized into unions of intersection types, and such normalized
21414+
// unions can get very large and expensive to relate. The following fast path checks if the source union
21415+
// originated in an intersection. If so, and if that intersection contains the target type, then we know
21416+
// the result to be true (for any two types A and B, A & B is related to both A and B).
21417+
const sourceOrigin = (source as UnionType).origin;
21418+
if (sourceOrigin && sourceOrigin.flags & TypeFlags.Intersection && target.aliasSymbol && contains((sourceOrigin as IntersectionType).types, target)) {
21419+
return Ternary.True;
21420+
}
21421+
// Similarly, in unions of unions the we preserve the original list of unions. This original list is often
21422+
// much shorter than the normalized result, so we scan it in the following fast path.
21423+
const targetOrigin = (target as UnionType).origin;
21424+
if (targetOrigin && targetOrigin.flags & TypeFlags.Union && source.aliasSymbol && contains((targetOrigin as UnionType).types, source)) {
21425+
return Ternary.True;
21426+
}
2141921427
}
2142021428
return relation === comparableRelation ?
2142121429
someTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive), intersectionState) :

0 commit comments

Comments
 (0)