Skip to content

Commit 82d68fc

Browse files
author
Andy Hanson
committed
Don't use a cached union/intersection type if there is an aliasSymbol
1 parent 8fa1d2e commit 82d68fc

36 files changed

+858
-831
lines changed

src/compiler/checker.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7344,17 +7344,27 @@ namespace ts {
73447344
if (types.length === 1) {
73457345
return types[0];
73467346
}
7347+
if (aliasSymbol) {
7348+
// Don't reuse types that would have different `aliasSymbol`s.
7349+
return create();
7350+
}
7351+
73477352
const id = getTypeListId(types);
73487353
let type = unionTypes.get(id);
73497354
if (!type) {
7350-
const propagatedFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
7351-
type = <UnionType>createType(TypeFlags.Union | propagatedFlags);
7355+
type = create();
73527356
unionTypes.set(id, type);
7357+
}
7358+
return type;
7359+
7360+
function create() {
7361+
const propagatedFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
7362+
const type = <UnionType>createType(TypeFlags.Union | propagatedFlags);
73537363
type.types = types;
73547364
type.aliasSymbol = aliasSymbol;
73557365
type.aliasTypeArguments = aliasTypeArguments;
7366+
return type;
73567367
}
7357-
return type;
73587368
}
73597369

73607370
function getTypeFromUnionTypeNode(node: UnionTypeNode): Type {
@@ -7437,17 +7447,27 @@ namespace ts {
74377447
return getUnionType(map(unionType.types, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))),
74387448
/*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
74397449
}
7450+
if (aliasSymbol) {
7451+
// Don't reuse types that would have different `aliasSymbol`s.
7452+
return create();
7453+
}
7454+
74407455
const id = getTypeListId(typeSet);
74417456
let type = intersectionTypes.get(id);
74427457
if (!type) {
7443-
const propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable);
7444-
type = <IntersectionType>createType(TypeFlags.Intersection | propagatedFlags);
7458+
type = create();
74457459
intersectionTypes.set(id, type);
7460+
}
7461+
return type;
7462+
7463+
function create(): IntersectionType {
7464+
const propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable);
7465+
const type = <IntersectionType>createType(TypeFlags.Intersection | propagatedFlags);
74467466
type.types = typeSet;
74477467
type.aliasSymbol = aliasSymbol;
74487468
type.aliasTypeArguments = aliasTypeArguments;
7469+
return type;
74497470
}
7450-
return type;
74517471
}
74527472

74537473
function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode): Type {

tests/baselines/reference/booleanLiteralTypes1.types

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
=== tests/cases/conformance/types/literal/booleanLiteralTypes1.ts ===
22
type A1 = true | false;
3-
>A1 : boolean
3+
>A1 : A1
44
>true : true
55
>false : false
66

77
type A2 = false | true;
8-
>A2 : boolean
8+
>A2 : A2
99
>false : false
1010
>true : true
1111

1212
function f1() {
1313
>f1 : () => void
1414

1515
var a: A1;
16-
>a : boolean
17-
>A1 : boolean
16+
>a : A1
17+
>A1 : A1
1818

1919
var a: A2;
20-
>a : boolean
21-
>A2 : boolean
20+
>a : A1
21+
>A2 : A2
2222

2323
var a: true | false;
24-
>a : boolean
24+
>a : A1
2525
>true : true
2626
>false : false
2727

2828
var a: false | true;
29-
>a : boolean
29+
>a : A1
3030
>false : false
3131
>true : true
3232
}

tests/baselines/reference/booleanLiteralTypes2.types

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
=== tests/cases/conformance/types/literal/booleanLiteralTypes2.ts ===
22
type A1 = true | false;
3-
>A1 : boolean
3+
>A1 : A1
44
>true : true
55
>false : false
66

77
type A2 = false | true;
8-
>A2 : boolean
8+
>A2 : A2
99
>false : false
1010
>true : true
1111

1212
function f1() {
1313
>f1 : () => void
1414

1515
var a: A1;
16-
>a : boolean
17-
>A1 : boolean
16+
>a : A1
17+
>A1 : A1
1818

1919
var a: A2;
20-
>a : boolean
21-
>A2 : boolean
20+
>a : A1
21+
>A2 : A2
2222

2323
var a: true | false;
24-
>a : boolean
24+
>a : A1
2525
>true : true
2626
>false : false
2727

2828
var a: false | true;
29-
>a : boolean
29+
>a : A1
3030
>false : false
3131
>true : true
3232
}

tests/baselines/reference/declarationEmitInferedTypeAlias5.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,5 @@ exports.v = v;
2525
//// [0.d.ts]
2626
export declare type Data = string | boolean;
2727
//// [1.d.ts]
28-
import * as Z from "./0";
29-
declare let v: Z.Data;
28+
declare let v: string | boolean;
3029
export { v };

tests/baselines/reference/declarationEmitInferedTypeAlias5.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ import * as Z from "./0"
1313

1414
//let v2: Z.Data;
1515
let v = "str" || true;
16-
>v : Z.Data
16+
>v : string | boolean
1717
>"str" || true : true | "str"
1818
>"str" : "str"
1919
>true : true
2020

2121
export { v }
22-
>v : Z.Data
22+
>v : string | boolean
2323

tests/baselines/reference/enumLiteralTypes1.types

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ type YesNo = Choice.Yes | Choice.No;
1313
>No : Choice.No
1414

1515
type NoYes = Choice.No | Choice.Yes;
16-
>NoYes : YesNo
16+
>NoYes : NoYes
1717
>Choice : any
1818
>No : Choice.No
1919
>Choice : any
2020
>Yes : Choice.Yes
2121

2222
type UnknownYesNo = Choice.Unknown | Choice.Yes | Choice.No;
23-
>UnknownYesNo : Choice
23+
>UnknownYesNo : UnknownYesNo
2424
>Choice : any
2525
>Unknown : Choice.Unknown
2626
>Choice : any
@@ -37,7 +37,7 @@ function f1() {
3737

3838
var a: NoYes;
3939
>a : YesNo
40-
>NoYes : YesNo
40+
>NoYes : NoYes
4141

4242
var a: Choice.Yes | Choice.No;
4343
>a : YesNo
@@ -55,17 +55,17 @@ function f1() {
5555
}
5656

5757
function f2(a: YesNo, b: UnknownYesNo, c: Choice) {
58-
>f2 : (a: YesNo, b: Choice, c: Choice) => void
58+
>f2 : (a: YesNo, b: UnknownYesNo, c: Choice) => void
5959
>a : YesNo
6060
>YesNo : YesNo
61-
>b : Choice
62-
>UnknownYesNo : Choice
61+
>b : UnknownYesNo
62+
>UnknownYesNo : UnknownYesNo
6363
>c : Choice
6464
>Choice : Choice
6565

6666
b = a;
6767
>b = a : YesNo
68-
>b : Choice
68+
>b : UnknownYesNo
6969
>a : YesNo
7070

7171
c = a;
@@ -74,9 +74,9 @@ function f2(a: YesNo, b: UnknownYesNo, c: Choice) {
7474
>a : YesNo
7575

7676
c = b;
77-
>c = b : YesNo
77+
>c = b : Choice.Yes | Choice.No
7878
>c : Choice
79-
>b : YesNo
79+
>b : Choice.Yes | Choice.No
8080
}
8181

8282
function f3(a: Choice.Yes, b: YesNo) {
@@ -234,11 +234,11 @@ declare function g(x: Choice): number;
234234
>Choice : Choice
235235

236236
function f5(a: YesNo, b: UnknownYesNo, c: Choice) {
237-
>f5 : (a: YesNo, b: Choice, c: Choice) => void
237+
>f5 : (a: YesNo, b: UnknownYesNo, c: Choice) => void
238238
>a : YesNo
239239
>YesNo : YesNo
240-
>b : Choice
241-
>UnknownYesNo : Choice
240+
>b : UnknownYesNo
241+
>UnknownYesNo : UnknownYesNo
242242
>c : Choice
243243
>Choice : Choice
244244

@@ -268,7 +268,7 @@ function f5(a: YesNo, b: UnknownYesNo, c: Choice) {
268268
>z4 : number
269269
>g(b) : number
270270
>g : { (x: Choice.Yes): string; (x: Choice.No): boolean; (x: Choice): number; }
271-
>b : Choice
271+
>b : UnknownYesNo
272272

273273
var z5 = g(c);
274274
>z5 : number
@@ -336,30 +336,30 @@ function f11(x: YesNo) {
336336
}
337337

338338
function f12(x: UnknownYesNo) {
339-
>f12 : (x: Choice) => void
340-
>x : Choice
341-
>UnknownYesNo : Choice
339+
>f12 : (x: UnknownYesNo) => void
340+
>x : UnknownYesNo
341+
>UnknownYesNo : UnknownYesNo
342342

343343
if (x) {
344-
>x : Choice
344+
>x : UnknownYesNo
345345

346346
x;
347-
>x : YesNo
347+
>x : Choice.Yes | Choice.No
348348
}
349349
else {
350350
x;
351-
>x : Choice
351+
>x : UnknownYesNo
352352
}
353353
}
354354

355355
function f13(x: UnknownYesNo) {
356-
>f13 : (x: Choice) => void
357-
>x : Choice
358-
>UnknownYesNo : Choice
356+
>f13 : (x: UnknownYesNo) => void
357+
>x : UnknownYesNo
358+
>UnknownYesNo : UnknownYesNo
359359

360360
if (x === Choice.Yes) {
361361
>x === Choice.Yes : boolean
362-
>x : Choice
362+
>x : UnknownYesNo
363363
>Choice.Yes : Choice.Yes
364364
>Choice : typeof Choice
365365
>Yes : Choice.Yes
@@ -394,9 +394,9 @@ function f20(x: Item) {
394394
>Item : Item
395395

396396
switch (x.kind) {
397-
>x.kind : YesNo
397+
>x.kind : Choice.Yes | Choice.No
398398
>x : Item
399-
>kind : YesNo
399+
>kind : Choice.Yes | Choice.No
400400

401401
case Choice.Yes: return x.a;
402402
>Choice.Yes : Choice.Yes
@@ -422,9 +422,9 @@ function f21(x: Item) {
422422
>Item : Item
423423

424424
switch (x.kind) {
425-
>x.kind : YesNo
425+
>x.kind : Choice.Yes | Choice.No
426426
>x : Item
427-
>kind : YesNo
427+
>kind : Choice.Yes | Choice.No
428428

429429
case Choice.Yes: return x.a;
430430
>Choice.Yes : Choice.Yes

0 commit comments

Comments
 (0)