Skip to content

Commit cbf1b04

Browse files
committed
Introduce two fastpasths into isRelatedTo
1 parent 853381c commit cbf1b04

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

src/compiler/checker.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15457,6 +15457,16 @@ namespace ts {
1545715457
return isIdenticalTo(source, target);
1545815458
}
1545915459

15460+
15461+
// We fastpath comparing a type parameter to exactly its constraint, as this is _super_ common,
15462+
// and otherwise, for type parameters in large unions, causes us to need to compare the union to itself,
15463+
// as we break down the _target_ union first, _then_ get the source constraint - so for every
15464+
// member of the target, we attempt to find a match in the source. This avoids that in cases where
15465+
// the target is exactly the constraint.
15466+
if (source.flags & TypeFlags.TypeParameter && getConstraintOfType(source) === target) {
15467+
return Ternary.True;
15468+
}
15469+
1546015470
// Try to see if we're relating something like `Foo` -> `Bar | null | undefined`.
1546115471
// If so, reporting the `null` and `undefined` in the type is hardly useful.
1546215472
// First, see if we're even relating an object type to a union.
@@ -15787,7 +15797,16 @@ namespace ts {
1578715797
function eachTypeRelatedToType(source: UnionOrIntersectionType, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
1578815798
let result = Ternary.True;
1578915799
const sourceTypes = source.types;
15790-
for (const sourceType of sourceTypes) {
15800+
for (let i = 0; i < sourceTypes.length; i++) {
15801+
const sourceType = sourceTypes[i];
15802+
if (target.flags & TypeFlags.Union && (target as UnionType).types.length === sourceTypes.length) {
15803+
// many unions are mappings of one another; in such cases, simply comparing members at the same index can shortcut the comparison
15804+
const related = isRelatedTo(sourceType, (target as UnionType).types[i], /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
15805+
if (related) {
15806+
result &= related;
15807+
continue;
15808+
}
15809+
}
1579115810
const related = isRelatedTo(sourceType, target, reportErrors, /*headMessage*/ undefined, intersectionState);
1579215811
if (!related) {
1579315812
return Ternary.False;

0 commit comments

Comments
 (0)