Skip to content

Commit 0406af1

Browse files
committed
Add union and intersection types to unions by type list id
1 parent 3cfd6d2 commit 0406af1

File tree

5 files changed

+103
-3
lines changed

5 files changed

+103
-3
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16593,7 +16593,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1659316593
function addTypeToIntersection(typeSet: Map<string, Type>, includes: TypeFlags, type: Type) {
1659416594
const flags = type.flags;
1659516595
if (flags & TypeFlags.Intersection) {
16596-
return addTypesToIntersection(typeSet, includes, (type as IntersectionType).types);
16596+
const list = `&${getTypeListId((type as IntersectionType).types)}`;
16597+
if (!typeSet.has(list)) {
16598+
typeSet.set(list, unknownType); // set the set as containing this intersection, so later copies aren't iterated over - `unknown` should be a noop set member
16599+
return addTypesToIntersection(typeSet, includes, (type as IntersectionType).types);
16600+
}
16601+
return includes;
1659716602
}
1659816603
if (isEmptyAnonymousObjectType(type)) {
1659916604
if (!(includes & TypeFlags.IncludesEmptyObject)) {
@@ -16610,13 +16615,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1661016615
includes |= TypeFlags.IncludesMissingType;
1661116616
type = undefinedType;
1661216617
}
16613-
if (!typeSet.has(type.id.toString())) {
16618+
const id = type.flags & TypeFlags.Union ? `|${getTypeListId((type as UnionType).types)}` : type.id.toString();
16619+
if (!typeSet.has(id)) {
1661416620
if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) {
1661516621
// We have seen two distinct unit types which means we should reduce to an
1661616622
// empty intersection. Adding TypeFlags.NonPrimitive causes that to happen.
1661716623
includes |= TypeFlags.NonPrimitive;
1661816624
}
16619-
typeSet.set(type.id.toString(), type);
16625+
typeSet.set(id, type);
1662016626
}
1662116627
}
1662216628
includes |= flags & TypeFlags.IncludesMask;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [intersectionOfIdenticalTypesNotComplex.ts]
2+
// Just a short block to make a union with > 300 unique members
3+
export type Bit = 0 | 1;
4+
export type SyntaxKind = `${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}`
5+
type NodeMaker<T extends SyntaxKind = SyntaxKind> = T extends T ? {kind: T}: never;
6+
7+
type Node = NodeMaker;
8+
type Ok = Node & Node;
9+
10+
type Node2 = NodeMaker;
11+
type Wat = Node & Node2;
12+
13+
//// [intersectionOfIdenticalTypesNotComplex.js]
14+
"use strict";
15+
Object.defineProperty(exports, "__esModule", { value: true });
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
=== tests/cases/compiler/intersectionOfIdenticalTypesNotComplex.ts ===
2+
// Just a short block to make a union with > 300 unique members
3+
export type Bit = 0 | 1;
4+
>Bit : Symbol(Bit, Decl(intersectionOfIdenticalTypesNotComplex.ts, 0, 0))
5+
6+
export type SyntaxKind = `${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}`
7+
>SyntaxKind : Symbol(SyntaxKind, Decl(intersectionOfIdenticalTypesNotComplex.ts, 1, 24))
8+
>Bit : Symbol(Bit, Decl(intersectionOfIdenticalTypesNotComplex.ts, 0, 0))
9+
>Bit : Symbol(Bit, Decl(intersectionOfIdenticalTypesNotComplex.ts, 0, 0))
10+
>Bit : Symbol(Bit, Decl(intersectionOfIdenticalTypesNotComplex.ts, 0, 0))
11+
>Bit : Symbol(Bit, Decl(intersectionOfIdenticalTypesNotComplex.ts, 0, 0))
12+
>Bit : Symbol(Bit, Decl(intersectionOfIdenticalTypesNotComplex.ts, 0, 0))
13+
>Bit : Symbol(Bit, Decl(intersectionOfIdenticalTypesNotComplex.ts, 0, 0))
14+
>Bit : Symbol(Bit, Decl(intersectionOfIdenticalTypesNotComplex.ts, 0, 0))
15+
>Bit : Symbol(Bit, Decl(intersectionOfIdenticalTypesNotComplex.ts, 0, 0))
16+
>Bit : Symbol(Bit, Decl(intersectionOfIdenticalTypesNotComplex.ts, 0, 0))
17+
18+
type NodeMaker<T extends SyntaxKind = SyntaxKind> = T extends T ? {kind: T}: never;
19+
>NodeMaker : Symbol(NodeMaker, Decl(intersectionOfIdenticalTypesNotComplex.ts, 2, 81))
20+
>T : Symbol(T, Decl(intersectionOfIdenticalTypesNotComplex.ts, 3, 15))
21+
>SyntaxKind : Symbol(SyntaxKind, Decl(intersectionOfIdenticalTypesNotComplex.ts, 1, 24))
22+
>SyntaxKind : Symbol(SyntaxKind, Decl(intersectionOfIdenticalTypesNotComplex.ts, 1, 24))
23+
>T : Symbol(T, Decl(intersectionOfIdenticalTypesNotComplex.ts, 3, 15))
24+
>T : Symbol(T, Decl(intersectionOfIdenticalTypesNotComplex.ts, 3, 15))
25+
>kind : Symbol(kind, Decl(intersectionOfIdenticalTypesNotComplex.ts, 3, 67))
26+
>T : Symbol(T, Decl(intersectionOfIdenticalTypesNotComplex.ts, 3, 15))
27+
28+
type Node = NodeMaker;
29+
>Node : Symbol(Node, Decl(intersectionOfIdenticalTypesNotComplex.ts, 3, 83))
30+
>NodeMaker : Symbol(NodeMaker, Decl(intersectionOfIdenticalTypesNotComplex.ts, 2, 81))
31+
32+
type Ok = Node & Node;
33+
>Ok : Symbol(Ok, Decl(intersectionOfIdenticalTypesNotComplex.ts, 5, 22))
34+
>Node : Symbol(Node, Decl(intersectionOfIdenticalTypesNotComplex.ts, 3, 83))
35+
>Node : Symbol(Node, Decl(intersectionOfIdenticalTypesNotComplex.ts, 3, 83))
36+
37+
type Node2 = NodeMaker;
38+
>Node2 : Symbol(Node2, Decl(intersectionOfIdenticalTypesNotComplex.ts, 6, 22))
39+
>NodeMaker : Symbol(NodeMaker, Decl(intersectionOfIdenticalTypesNotComplex.ts, 2, 81))
40+
41+
type Wat = Node & Node2;
42+
>Wat : Symbol(Wat, Decl(intersectionOfIdenticalTypesNotComplex.ts, 8, 23))
43+
>Node : Symbol(Node, Decl(intersectionOfIdenticalTypesNotComplex.ts, 3, 83))
44+
>Node2 : Symbol(Node2, Decl(intersectionOfIdenticalTypesNotComplex.ts, 6, 22))
45+

0 commit comments

Comments
 (0)