Skip to content

Commit 14f30d3

Browse files
committed
Sort cache key / cache last type instead of just last union
1 parent 46d1c4e commit 14f30d3

File tree

1 file changed

+11
-13
lines changed

1 file changed

+11
-13
lines changed

src/compiler/checker.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16257,19 +16257,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1625716257
// Add the given types to the given type set. Order is preserved, duplicates are removed,
1625816258
// and nested types of the given kind are flattened into the set.
1625916259
function addTypesToUnion(typeSet: Type[], includes: TypeFlags, types: readonly Type[]): TypeFlags {
16260-
let lastUnion: Type | undefined;
16260+
let lastType: Type | undefined;
1626116261
for (const type of types) {
16262-
if (type.flags & TypeFlags.Union) {
16263-
// We skip the union type if it is the same as the last union we processed. We could potentially track
16264-
// all union types that we've processed, but this simple test is fast and covers the scenarios we care
16265-
// about (in particular, Record<A, B>[A], where A and B are large union types).
16266-
if (type !== lastUnion) {
16267-
includes = addTypesToUnion(typeSet, includes | (isNamedUnionType(type) ? TypeFlags.Union : 0), (type as UnionType).types);
16268-
lastUnion = type;
16269-
}
16270-
}
16271-
else {
16272-
includes = addTypeToUnion(typeSet, includes, type);
16262+
// We skip the type if it is the same as the last type we processed. This simple test particularly
16263+
// saves a lot of work for large lists of the same union type, such as when resolving `Record<A, B>[A]`,
16264+
// where A and B are large union types.
16265+
if (type !== lastType) {
16266+
includes = type.flags & TypeFlags.Union ?
16267+
addTypesToUnion(typeSet, includes | (isNamedUnionType(type) ? TypeFlags.Union : 0), (type as UnionType).types) :
16268+
addTypeToUnion(typeSet, includes, type);
16269+
lastType = type;
1627316270
}
1627416271
}
1627516272
return includes;
@@ -16425,7 +16422,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1642516422
// We optimize for the common case of unioning a union type with some other type (such as `undefined`).
1642616423
if (types.length === 2 && !origin && (types[0].flags & TypeFlags.Union || types[1].flags & TypeFlags.Union)) {
1642716424
const infix = unionReduction === UnionReduction.None ? "N" : unionReduction === UnionReduction.Subtype ? "S" : "L";
16428-
const id = types[0].id + infix + types[1].id + getAliasId(aliasSymbol, aliasTypeArguments);
16425+
const index = types[0].id < types[1].id ? 0 : 1;
16426+
const id = types[index].id + infix + types[1 - index].id + getAliasId(aliasSymbol, aliasTypeArguments);
1642916427
let type = unionOfUnionTypes.get(id);
1643016428
if (!type) {
1643116429
type = getUnionTypeWorker(types, unionReduction, aliasSymbol, aliasTypeArguments, origin);

0 commit comments

Comments
 (0)