Skip to content

Commit 5a79b0c

Browse files
authored
Improve type ordering (#1284)
1 parent 0565313 commit 5a79b0c

File tree

3 files changed

+32
-6
lines changed

3 files changed

+32
-6
lines changed

internal/checker/types.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,12 @@ type SignatureLinks struct {
408408

409409
type TypeFlags uint32
410410

411+
// Note that for types of different kinds, the numeric values of TypeFlags determine the order
412+
// computed by the CompareTypes function and therefore the order of constituent types in union types.
413+
// Since union type processing often bails out early when a result is known, it is important to order
414+
// TypeFlags in increasing order of potential type complexity. In particular, indexed access and
415+
// conditional types should sort last as those types are potentially recursive and possibly infinite.
416+
411417
const (
412418
TypeFlagsNone TypeFlags = 0
413419
TypeFlagsAny TypeFlags = 1 << 0
@@ -432,11 +438,11 @@ const (
432438
TypeFlagsTypeParameter TypeFlags = 1 << 19 // Type parameter
433439
TypeFlagsObject TypeFlags = 1 << 20 // Object type
434440
TypeFlagsIndex TypeFlags = 1 << 21 // keyof T
435-
TypeFlagsIndexedAccess TypeFlags = 1 << 22 // T[K]
436-
TypeFlagsConditional TypeFlags = 1 << 23 // T extends U ? X : Y
441+
TypeFlagsTemplateLiteral TypeFlags = 1 << 22 // Template literal type
442+
TypeFlagsStringMapping TypeFlags = 1 << 23 // Uppercase/Lowercase type
437443
TypeFlagsSubstitution TypeFlags = 1 << 24 // Type parameter substitution
438-
TypeFlagsTemplateLiteral TypeFlags = 1 << 25 // Template literal type
439-
TypeFlagsStringMapping TypeFlags = 1 << 26 // Uppercase/Lowercase type
444+
TypeFlagsIndexedAccess TypeFlags = 1 << 25 // T[K]
445+
TypeFlagsConditional TypeFlags = 1 << 26 // T extends U ? X : Y
440446
TypeFlagsUnion TypeFlags = 1 << 27 // Union (T | U)
441447
TypeFlagsIntersection TypeFlags = 1 << 28 // Intersection (T & U)
442448
TypeFlagsReserved1 TypeFlags = 1 << 29 // Used by union/intersection type construction

testdata/baselines/reference/submodule/compiler/awaitedTypeNoLib.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ error TS2318: Cannot find global type 'String'.
1010
awaitedTypeNoLib.ts(3,15): error TS2304: Cannot find name 'PromiseLike'.
1111
awaitedTypeNoLib.ts(18,27): error TS2345: Argument of type 'Thenable<NotPromise<TResult>> | NotPromise<TResult>' is not assignable to parameter of type 'Thenable<TResult>'.
1212
Type 'NotPromise<TResult>' is not assignable to type 'Thenable<TResult>'.
13-
Type '(TResult extends PromiseLike<unknown> ? never : TResult) | TResult' is not assignable to type 'Thenable<TResult>'.
13+
Type 'TResult | (TResult extends PromiseLike<unknown> ? never : TResult)' is not assignable to type 'Thenable<TResult>'.
1414
Type 'Thenable<unknown> & TResult' is not assignable to type 'Thenable<TResult>'.
1515
Type 'unknown' is not assignable to type 'TResult'.
1616
'TResult' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.
@@ -49,7 +49,7 @@ awaitedTypeNoLib.ts(18,27): error TS2345: Argument of type 'Thenable<NotPromise<
4949
~~~~~~
5050
!!! error TS2345: Argument of type 'Thenable<NotPromise<TResult>> | NotPromise<TResult>' is not assignable to parameter of type 'Thenable<TResult>'.
5151
!!! error TS2345: Type 'NotPromise<TResult>' is not assignable to type 'Thenable<TResult>'.
52-
!!! error TS2345: Type '(TResult extends PromiseLike<unknown> ? never : TResult) | TResult' is not assignable to type 'Thenable<TResult>'.
52+
!!! error TS2345: Type 'TResult | (TResult extends PromiseLike<unknown> ? never : TResult)' is not assignable to type 'Thenable<TResult>'.
5353
!!! error TS2345: Type 'Thenable<unknown> & TResult' is not assignable to type 'Thenable<TResult>'.
5454
!!! error TS2345: Type 'unknown' is not assignable to type 'TResult'.
5555
!!! error TS2345: 'TResult' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--- old.awaitedTypeNoLib.errors.txt
2+
+++ new.awaitedTypeNoLib.errors.txt
3+
@@= skipped -9, +9 lines =@@
4+
awaitedTypeNoLib.ts(3,15): error TS2304: Cannot find name 'PromiseLike'.
5+
awaitedTypeNoLib.ts(18,27): error TS2345: Argument of type 'Thenable<NotPromise<TResult>> | NotPromise<TResult>' is not assignable to parameter of type 'Thenable<TResult>'.
6+
Type 'NotPromise<TResult>' is not assignable to type 'Thenable<TResult>'.
7+
- Type '(TResult extends PromiseLike<unknown> ? never : TResult) | TResult' is not assignable to type 'Thenable<TResult>'.
8+
+ Type 'TResult | (TResult extends PromiseLike<unknown> ? never : TResult)' is not assignable to type 'Thenable<TResult>'.
9+
Type 'Thenable<unknown> & TResult' is not assignable to type 'Thenable<TResult>'.
10+
Type 'unknown' is not assignable to type 'TResult'.
11+
'TResult' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.
12+
@@= skipped -39, +39 lines =@@
13+
~~~~~~
14+
!!! error TS2345: Argument of type 'Thenable<NotPromise<TResult>> | NotPromise<TResult>' is not assignable to parameter of type 'Thenable<TResult>'.
15+
!!! error TS2345: Type 'NotPromise<TResult>' is not assignable to type 'Thenable<TResult>'.
16+
-!!! error TS2345: Type '(TResult extends PromiseLike<unknown> ? never : TResult) | TResult' is not assignable to type 'Thenable<TResult>'.
17+
+!!! error TS2345: Type 'TResult | (TResult extends PromiseLike<unknown> ? never : TResult)' is not assignable to type 'Thenable<TResult>'.
18+
!!! error TS2345: Type 'Thenable<unknown> & TResult' is not assignable to type 'Thenable<TResult>'.
19+
!!! error TS2345: Type 'unknown' is not assignable to type 'TResult'.
20+
!!! error TS2345: 'TResult' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.

0 commit comments

Comments
 (0)