Skip to content

Commit 6aeb8c1

Browse files
authored
Preserve type aliases for union and intersection types (#42149)
* Create separate types for equivalent aliased unions * Accept new baselines * Preserve original types for union types * Accept new baselines * Preserve intersection origin for union types * Accept new baselines * Accept new baselines * Preserve aliases during relationship checks * Accept new baselines * Preserve aliases for intersection and indexed access types * Accept new baselines * Compute intersection-of-unions cross product without recursion * Accept new baselines * Use denormalized type objects for origin / support 'keyof' origins * Accept new baselines * Fix fourslash test * Recursively extract named union types * Accept new baselines * Map on union origin in mapType to better preserve aliases and origins * Remove redundant call * Accept new baselines * Revert back to declared type when branches produce equivalent union * Accept new baselines * Don't include denormal origin types in regular type statistics * Fix issue with unions not being marked primitive-only * Allow new alias to be associated with type alias instantiation * Accept new baselines * Revert "Accept new baselines" This reverts commit 4507270. * Revert "Allow new alias to be associated with type alias instantiation" This reverts commit 2c2d06d.
1 parent 0c58ede commit 6aeb8c1

File tree

142 files changed

+1071
-958
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+1071
-958
lines changed

src/compiler/checker.ts

Lines changed: 161 additions & 57 deletions
Large diffs are not rendered by default.

src/compiler/types.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5008,7 +5008,7 @@ namespace ts {
50085008
// This *should* be every type other than null, undefined, void, and never
50095009
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
50105010
/* @internal */
5011-
NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | StructuredOrInstantiable,
5011+
NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | Object | Intersection | Instantiable,
50125012
// The following flags are aggregated during union and intersection type construction
50135013
/* @internal */
50145014
IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive | TemplateLiteral,
@@ -5296,9 +5296,11 @@ namespace ts {
52965296

52975297
export interface UnionType extends UnionOrIntersectionType {
52985298
/* @internal */
5299-
resolvedReducedType: Type;
5299+
resolvedReducedType?: Type;
53005300
/* @internal */
5301-
regularType: UnionType;
5301+
regularType?: UnionType;
5302+
/* @internal */
5303+
origin?: Type; // Denormalized union, intersection, or index type in which union originates
53025304
}
53035305

53045306
export interface IntersectionType extends UnionOrIntersectionType {

tests/baselines/reference/assertionFunctionsCanNarrowByDiscriminant.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ animal.canMeow; // since is cat, should not be an error
4949
>canMeow : true
5050

5151
const animalOrUndef = { type: 'cat', canMeow: true } as Animal | undefined;
52-
>animalOrUndef : Cat | Dog | undefined
53-
>{ type: 'cat', canMeow: true } as Animal | undefined : Cat | Dog | undefined
52+
>animalOrUndef : Animal | undefined
53+
>{ type: 'cat', canMeow: true } as Animal | undefined : Animal | undefined
5454
>{ type: 'cat', canMeow: true } : { type: "cat"; canMeow: true; }
5555
>type : "cat"
5656
>'cat' : "cat"
@@ -61,7 +61,7 @@ assertEqual(animalOrUndef?.type, 'cat' as const);
6161
>assertEqual(animalOrUndef?.type, 'cat' as const) : void
6262
>assertEqual : <T>(value: any, type: T) => asserts value is T
6363
>animalOrUndef?.type : "cat" | "dog" | undefined
64-
>animalOrUndef : Cat | Dog | undefined
64+
>animalOrUndef : Animal | undefined
6565
>type : "cat" | "dog" | undefined
6666
>'cat' as const : "cat"
6767
>'cat' : "cat"

tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
66
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts(58,5): error TS2322: Type 'S' is not assignable to type 'T'.
77
Property 'c' is missing in type 'S' but required in type '{ a: 2; b: 4 | 3; c: string; }'.
88
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts(82,5): error TS2322: Type 'S' is not assignable to type 'T'.
9-
Type 'S' is not assignable to type '{ a: 0 | 2 | 1; b: 0 | 2 | 1; c: 2; }'.
9+
Type 'S' is not assignable to type '{ a: N; b: N; c: 2; }'.
1010
Types of property 'c' are incompatible.
11-
Type '0 | 2 | 1' is not assignable to type '2'.
11+
Type 'N' is not assignable to type '2'.
1212
Type '0' is not assignable to type '2'.
1313

1414

@@ -107,9 +107,9 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
107107
t = s;
108108
~
109109
!!! error TS2322: Type 'S' is not assignable to type 'T'.
110-
!!! error TS2322: Type 'S' is not assignable to type '{ a: 0 | 2 | 1; b: 0 | 2 | 1; c: 2; }'.
110+
!!! error TS2322: Type 'S' is not assignable to type '{ a: N; b: N; c: 2; }'.
111111
!!! error TS2322: Types of property 'c' are incompatible.
112-
!!! error TS2322: Type '0 | 2 | 1' is not assignable to type '2'.
112+
!!! error TS2322: Type 'N' is not assignable to type '2'.
113113
!!! error TS2322: Type '0' is not assignable to type '2'.
114114
}
115115

tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.types

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -155,58 +155,58 @@ namespace Example5 {
155155
// 3 discriminant properties with 3 types a piece
156156
// is 27 possible combinations.
157157
type N = 0 | 1 | 2;
158-
>N : 0 | 2 | 1
158+
>N : N
159159

160160
type S = { a: N, b: N, c: N };
161161
>S : S
162-
>a : 0 | 2 | 1
163-
>b : 0 | 2 | 1
164-
>c : 0 | 2 | 1
162+
>a : N
163+
>b : N
164+
>c : N
165165

166166
type T = { a: 0, b: N, c: N }
167167
>T : T
168168
>a : 0
169-
>b : 0 | 2 | 1
170-
>c : 0 | 2 | 1
169+
>b : N
170+
>c : N
171171

172172
| { a: 1, b: N, c: N }
173173
>a : 1
174-
>b : 0 | 2 | 1
175-
>c : 0 | 2 | 1
174+
>b : N
175+
>c : N
176176

177177
| { a: 2, b: N, c: N }
178178
>a : 2
179-
>b : 0 | 2 | 1
180-
>c : 0 | 2 | 1
179+
>b : N
180+
>c : N
181181

182182
| { a: N, b: 0, c: N }
183-
>a : 0 | 2 | 1
183+
>a : N
184184
>b : 0
185-
>c : 0 | 2 | 1
185+
>c : N
186186

187187
| { a: N, b: 1, c: N }
188-
>a : 0 | 2 | 1
188+
>a : N
189189
>b : 1
190-
>c : 0 | 2 | 1
190+
>c : N
191191

192192
| { a: N, b: 2, c: N }
193-
>a : 0 | 2 | 1
193+
>a : N
194194
>b : 2
195-
>c : 0 | 2 | 1
195+
>c : N
196196

197197
| { a: N, b: N, c: 0 }
198-
>a : 0 | 2 | 1
199-
>b : 0 | 2 | 1
198+
>a : N
199+
>b : N
200200
>c : 0
201201

202202
| { a: N, b: N, c: 1 }
203-
>a : 0 | 2 | 1
204-
>b : 0 | 2 | 1
203+
>a : N
204+
>b : N
205205
>c : 1
206206

207207
| { a: N, b: N, c: 2 };
208-
>a : 0 | 2 | 1
209-
>b : 0 | 2 | 1
208+
>a : N
209+
>b : N
210210
>c : 2
211211

212212
declare let s: S;
@@ -359,9 +359,9 @@ namespace GH12052 {
359359

360360
good.type = getAxisType();
361361
>good.type = getAxisType() : IAxisType
362-
>good.type : IAxisType
362+
>good.type : "linear" | "categorical"
363363
>good : IAxis
364-
>type : IAxisType
364+
>type : "linear" | "categorical"
365365
>getAxisType() : IAxisType
366366
>getAxisType : () => IAxisType
367367
}
@@ -473,17 +473,17 @@ namespace GH39357 {
473473
>A : A
474474

475475
type B = "a" | "b" | "c";
476-
>B : "a" | "b" | "c"
476+
>B : B
477477

478478
declare const b: B;
479-
>b : "a" | "b" | "c"
479+
>b : B
480480

481481
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
482482
>a : A
483483
>b === "a" || b === "b" ? [b, 1] : ["c", ""] : ["a" | "b", number] | ["c", string]
484484
>b === "a" || b === "b" : boolean
485485
>b === "a" : boolean
486-
>b : "a" | "b" | "c"
486+
>b : B
487487
>"a" : "a"
488488
>b === "b" : boolean
489489
>b : "b" | "c"

tests/baselines/reference/booleanLiteralTypes1.types

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
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
16+
>a : A1
1717

1818
var a: A2;
19-
>a : boolean
19+
>a : A1
2020

2121
var a: true | false;
22-
>a : boolean
22+
>a : A1
2323
>true : true
2424
>false : false
2525

2626
var a: false | true;
27-
>a : boolean
27+
>a : A1
2828
>false : false
2929
>true : true
3030
}

tests/baselines/reference/booleanLiteralTypes2.types

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
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
16+
>a : A1
1717

1818
var a: A2;
19-
>a : boolean
19+
>a : A1
2020

2121
var a: true | false;
22-
>a : boolean
22+
>a : A1
2323
>true : true
2424
>false : false
2525

2626
var a: false | true;
27-
>a : boolean
27+
>a : A1
2828
>false : false
2929
>true : true
3030
}

tests/baselines/reference/callsOnComplexSignatures.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ function test1() {
3030
>t : Temp1 | Temp2
3131

3232
const z = t.getValue("bar"); // Should be fine
33-
>z : React.ReactText
34-
>t.getValue("bar") : React.ReactText
33+
>z : string | number
34+
>t.getValue("bar") : string | number
3535
>t.getValue : ((name: "foo" | "bar") => number) | ((name: "bar" | "baz") => string)
3636
>t : Temp1 | Temp2
3737
>getValue : ((name: "foo" | "bar") => number) | ((name: "bar" | "baz") => string)
@@ -399,7 +399,7 @@ function test5() {
399399
}
400400

401401
var C: React.ComponentType<P1> | React.ComponentType<P2> = null as any;
402-
>C : React.ComponentClass<P1, any> | React.StatelessComponent<P1> | React.ComponentClass<P2, any> | React.StatelessComponent<P2>
402+
>C : React.ComponentType<P1> | React.ComponentType<P2>
403403
>React : any
404404
>React : any
405405
>null as any : any
@@ -408,7 +408,7 @@ function test5() {
408408
const a = <C p={true} />;
409409
>a : JSX.Element
410410
><C p={true} /> : JSX.Element
411-
>C : React.ComponentClass<P1, any> | React.StatelessComponent<P1> | React.ComponentClass<P2, any> | React.StatelessComponent<P2>
411+
>C : React.ComponentType<P1> | React.ComponentType<P2>
412412
>p : true
413413
>true : true
414414
}

0 commit comments

Comments
 (0)