Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort unions without using type IDs #61399

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
392 changes: 386 additions & 6 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@ export function binarySearchKey<T, U>(array: readonly T[], key: U, keySelector:
while (low <= high) {
const middle = low + ((high - low) >> 1);
const midKey = keySelector(array[middle], middle);
switch (keyComparer(midKey, key)) {
switch (Math.sign(keyComparer(midKey, key))) {
case Comparison.LessThan:
low = middle + 1;
break;
Expand Down Expand Up @@ -1967,9 +1967,11 @@ export function equateStringsCaseSensitive(a: string, b: string): boolean {
return equateValues(a, b);
}

function compareComparableValues(a: string | undefined, b: string | undefined): Comparison;
function compareComparableValues(a: number | undefined, b: number | undefined): Comparison;
function compareComparableValues(a: string | number | undefined, b: string | number | undefined) {
/** @internal */
export function compareComparableValues(a: string | undefined, b: string | undefined): Comparison;
/** @internal */
export function compareComparableValues(a: number | undefined, b: number | undefined): Comparison;
export function compareComparableValues(a: string | number | undefined, b: string | number | undefined) {
return a === b ? Comparison.EqualTo :
a === undefined ? Comparison.LessThan :
b === undefined ? Comparison.GreaterThan :
Expand Down
40 changes: 21 additions & 19 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6269,21 +6269,21 @@ export interface SerializedTypeEntry {
export const enum TypeFlags {
Any = 1 << 0,
Unknown = 1 << 1,
String = 1 << 2,
Number = 1 << 3,
Boolean = 1 << 4,
Enum = 1 << 5, // Numeric computed enum member value
BigInt = 1 << 6,
StringLiteral = 1 << 7,
NumberLiteral = 1 << 8,
BooleanLiteral = 1 << 9,
EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union
BigIntLiteral = 1 << 11,
ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6
UniqueESSymbol = 1 << 13, // unique symbol
Void = 1 << 14,
Undefined = 1 << 15,
Null = 1 << 16,
Undefined = 1 << 2,
Null = 1 << 3,
Void = 1 << 4,
String = 1 << 5,
Number = 1 << 6,
BigInt = 1 << 7,
Boolean = 1 << 8,
ESSymbol = 1 << 9, // Type of symbol primitive introduced in ES6
StringLiteral = 1 << 10,
NumberLiteral = 1 << 11,
BooleanLiteral = 1 << 12,
BigIntLiteral = 1 << 13,
UniqueESSymbol = 1 << 14, // unique symbol
EnumLiteral = 1 << 15, // Always combined with StringLiteral, NumberLiteral, or Union
Enum = 1 << 16, // Numeric computed enum member value
Never = 1 << 17, // Never type
TypeParameter = 1 << 18, // Type parameter
Object = 1 << 19, // Object type
Expand Down Expand Up @@ -6484,15 +6484,17 @@ export const enum ObjectFlags {
PropagatingFlags = ContainsWideningType | ContainsObjectOrArrayLiteral | NonInferrableType,
/** @internal */
InstantiatedMapped = Mapped | Instantiated,
// Object flags that uniquely identify the kind of ObjectType
/** @internal */
ObjectTypeKindMask = ClassOrInterface | Reference | Tuple | Anonymous | Mapped | ReverseMapped | EvolvingArray,


// Flags that require TypeFlags.Object
ContainsSpread = 1 << 21, // Object literal contains spread operation
ObjectRestType = 1 << 22, // Originates in object rest declaration
InstantiationExpressionType = 1 << 23, // Originates in instantiation expression
SingleSignatureType = 1 << 27, // A single signature type extracted from a potentially broader type

// Object flags that uniquely identify the kind of ObjectType
/** @internal */
ObjectTypeKindMask = ClassOrInterface | Reference | Tuple | Anonymous | Mapped | ReverseMapped | EvolvingArray | InstantiationExpressionType | SingleSignatureType,

/** @internal */
IsClassInstanceClone = 1 << 24, // Type is a clone of a class instance type
// Flags that require TypeFlags.Object and ObjectFlags.Reference
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/TypeGuardWithArrayUnion.types
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ class Message {
function saySize(message: Message | Message[]) {
>saySize : (message: Message | Message[]) => number
> : ^ ^^ ^^^^^^^^^^^
>message : Message | Message[]
>message : Message[] | Message
> : ^^^^^^^^^^^^^^^^^^^

if (message instanceof Array) {
>message instanceof Array : boolean
> : ^^^^^^^
>message : Message | Message[]
>message : Message[] | Message
> : ^^^^^^^^^^^^^^^^^^^
>Array : ArrayConstructor
> : ^^^^^^^^^^^^^^^^
Expand Down
22 changes: 11 additions & 11 deletions tests/baselines/reference/TypeGuardWithEnumUnion.types
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function f1(x: Color | string) {
if (typeof x === "number") {
>typeof x === "number" : boolean
> : ^^^^^^^
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>typeof x : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>x : string | Color
> : ^^^^^^^^^^^^^^
Expand Down Expand Up @@ -53,15 +53,15 @@ function f1(x: Color | string) {
function f2(x: Color | string | string[]) {
>f2 : (x: Color | string | string[]) => void
> : ^ ^^ ^^^^^^^^^
>x : string | Color | string[]
>x : string | string[] | Color
> : ^^^^^^^^^^^^^^^^^^^^^^^^^

if (typeof x === "object") {
>typeof x === "object" : boolean
> : ^^^^^^^
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>typeof x : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>x : string | Color | string[]
>x : string | string[] | Color
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
>"object" : "object"
> : ^^^^^^^^
Expand All @@ -79,9 +79,9 @@ function f2(x: Color | string | string[]) {
if (typeof x === "number") {
>typeof x === "number" : boolean
> : ^^^^^^^
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>typeof x : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>x : string | Color | string[]
>x : string | string[] | Color
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
>"number" : "number"
> : ^^^^^^^^
Expand Down Expand Up @@ -110,9 +110,9 @@ function f2(x: Color | string | string[]) {
if (typeof x === "string") {
>typeof x === "string" : boolean
> : ^^^^^^^
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>typeof x : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>x : string | Color | string[]
>x : string | string[] | Color
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
>"string" : "string"
> : ^^^^^^^^
Expand All @@ -129,13 +129,13 @@ function f2(x: Color | string | string[]) {
}
else {
var b = x;
>b : Color | string[]
>b : string[] | Color
> : ^^^^^^^^^^^^^^^^
>x : Color | string[]
>x : string[] | Color
> : ^^^^^^^^^^^^^^^^

var b: Color | string[];
>b : Color | string[]
>b : string[] | Color
> : ^^^^^^^^^^^^^^^^
}
}
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/ambientExportDefaultErrors.types
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ declare module "indirect" {
> : ^^^^^^^^^^^^^^^^^^^^^^^^^

export default typeof Foo.default;
>typeof Foo.default : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>typeof Foo.default : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Foo.default : number
> : ^^^^^^
Expand All @@ -58,7 +58,7 @@ declare module "indirect2" {
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^

export = typeof Foo2;
>typeof Foo2 : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>typeof Foo2 : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Foo2 : number
> : ^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/anonymousClassExpression1.types
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function f() {
return typeof class {} === "function";
>typeof class {} === "function" : boolean
> : ^^^^^^^
>typeof class {} : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>typeof class {} : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>class {} : typeof (Anonymous class)
> : ^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
56 changes: 28 additions & 28 deletions tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6570,21 +6570,21 @@ declare namespace ts {
enum TypeFlags {
Any = 1,
Unknown = 2,
String = 4,
Number = 8,
Boolean = 16,
Enum = 32,
BigInt = 64,
StringLiteral = 128,
NumberLiteral = 256,
BooleanLiteral = 512,
EnumLiteral = 1024,
BigIntLiteral = 2048,
ESSymbol = 4096,
UniqueESSymbol = 8192,
Void = 16384,
Undefined = 32768,
Null = 65536,
Undefined = 4,
Null = 8,
Void = 16,
String = 32,
Number = 64,
BigInt = 128,
Boolean = 256,
ESSymbol = 512,
StringLiteral = 1024,
NumberLiteral = 2048,
BooleanLiteral = 4096,
BigIntLiteral = 8192,
UniqueESSymbol = 16384,
EnumLiteral = 32768,
Enum = 65536,
Never = 131072,
TypeParameter = 262144,
Object = 524288,
Expand All @@ -6597,26 +6597,26 @@ declare namespace ts {
NonPrimitive = 67108864,
TemplateLiteral = 134217728,
StringMapping = 268435456,
Literal = 2944,
Unit = 109472,
Freshable = 2976,
StringOrNumberLiteral = 384,
PossiblyFalsy = 117724,
StringLike = 402653316,
NumberLike = 296,
BigIntLike = 2112,
BooleanLike = 528,
EnumLike = 1056,
ESSymbolLike = 12288,
VoidLike = 49152,
Literal = 15360,
Unit = 97292,
Freshable = 80896,
StringOrNumberLiteral = 3072,
PossiblyFalsy = 15868,
StringLike = 402654240,
NumberLike = 67648,
BigIntLike = 8320,
BooleanLike = 4352,
EnumLike = 98304,
ESSymbolLike = 16896,
VoidLike = 20,
UnionOrIntersection = 3145728,
StructuredType = 3670016,
TypeVariable = 8650752,
InstantiableNonPrimitive = 58982400,
InstantiablePrimitive = 406847488,
Instantiable = 465829888,
StructuredOrInstantiable = 469499904,
Narrowable = 536624127,
Narrowable = 536707043,
}
type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
interface Type {
Expand Down
32 changes: 16 additions & 16 deletions tests/baselines/reference/arrayBestCommonTypes.types
Original file line number Diff line number Diff line change
Expand Up @@ -620,10 +620,10 @@ module EmptyTypes {
> : ^^^^^^^^^^^^

var b1 = [baseObj, base2Obj, ifaceObj];
>b1 : iface[]
> : ^^^^^^^
>[baseObj, base2Obj, ifaceObj] : iface[]
> : ^^^^^^^
>b1 : (base | base2)[]
> : ^^^^^^^^^^^^^^^^
>[baseObj, base2Obj, ifaceObj] : (base | base2)[]
> : ^^^^^^^^^^^^^^^^
>baseObj : base
> : ^^^^
>base2Obj : base2
Expand All @@ -632,10 +632,10 @@ module EmptyTypes {
> : ^^^^^

var b2 = [base2Obj, baseObj, ifaceObj];
>b2 : iface[]
> : ^^^^^^^
>[base2Obj, baseObj, ifaceObj] : iface[]
> : ^^^^^^^
>b2 : (base | base2)[]
> : ^^^^^^^^^^^^^^^^
>[base2Obj, baseObj, ifaceObj] : (base | base2)[]
> : ^^^^^^^^^^^^^^^^
>base2Obj : base2
> : ^^^^^
>baseObj : base
Expand All @@ -644,10 +644,10 @@ module EmptyTypes {
> : ^^^^^

var b3 = [baseObj, ifaceObj, base2Obj];
>b3 : iface[]
> : ^^^^^^^
>[baseObj, ifaceObj, base2Obj] : iface[]
> : ^^^^^^^
>b3 : (base | base2)[]
> : ^^^^^^^^^^^^^^^^
>[baseObj, ifaceObj, base2Obj] : (base | base2)[]
> : ^^^^^^^^^^^^^^^^
>baseObj : base
> : ^^^^
>ifaceObj : iface
Expand All @@ -656,10 +656,10 @@ module EmptyTypes {
> : ^^^^^

var b4 = [ifaceObj, baseObj, base2Obj];
>b4 : iface[]
> : ^^^^^^^
>[ifaceObj, baseObj, base2Obj] : iface[]
> : ^^^^^^^
>b4 : (base | base2)[]
> : ^^^^^^^^^^^^^^^^
>[ifaceObj, baseObj, base2Obj] : (base | base2)[]
> : ^^^^^^^^^^^^^^^^
>ifaceObj : iface
> : ^^^^^
>baseObj : base
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/arrayConcat3.types
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ function doStuff<T extends object, T1 extends T>(a: Array<Fn<T>>, b: Array<Fn<T1
b.concat(a);
>b.concat(a) : Fn<T1>[]
> : ^^^^^^^^
>b.concat : { (...items: ConcatArray<Fn<T1>>[]): Fn<T1>[]; (...items: (Fn<T1> | ConcatArray<Fn<T1>>)[]): Fn<T1>[]; }
>b.concat : { (...items: ConcatArray<Fn<T1>>[]): Fn<T1>[]; (...items: (ConcatArray<Fn<T1>> | Fn<T1>)[]): Fn<T1>[]; }
> : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>b : Fn<T1>[]
> : ^^^^^^^^
>concat : { (...items: ConcatArray<Fn<T1>>[]): Fn<T1>[]; (...items: (Fn<T1> | ConcatArray<Fn<T1>>)[]): Fn<T1>[]; }
>concat : { (...items: ConcatArray<Fn<T1>>[]): Fn<T1>[]; (...items: (ConcatArray<Fn<T1>> | Fn<T1>)[]): Fn<T1>[]; }
> : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>a : Fn<T>[]
> : ^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export function evaluate(expression: Expression): boolean {
return expression === 'true';
>expression === 'true' : boolean
> : ^^^^^^^
>expression : "true" | "false"
>expression : "false" | "true"
> : ^^^^^^^^^^^^^^^^
>'true' : "true"
> : ^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/arrayEvery.types
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const isString = (x: unknown): x is string => typeof x === 'string';
> : ^^^^^^^
>typeof x === 'string' : boolean
> : ^^^^^^^
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>typeof x : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>x : unknown
> : ^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/arrayFind.types
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function isNumber(x: any): x is number {
return typeof x === "number";
>typeof x === "number" : boolean
> : ^^^^^^^
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>typeof x : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>x : any
>"number" : "number"
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/arrayFlatNoCrashInference.types
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

=== arrayFlatNoCrashInference.ts ===
function foo<T>(arr: T[], depth: number) {
>foo : <T>(arr: T[], depth: number) => FlatArray<T, 0 | 1 | -1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20>[]
>foo : <T>(arr: T[], depth: number) => FlatArray<T, -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20>[]
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>arr : T[]
> : ^^^
>depth : number
> : ^^^^^^

return arr.flat(depth);
>arr.flat(depth) : FlatArray<T, 0 | 1 | -1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20>[]
>arr.flat(depth) : FlatArray<T, -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20>[]
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>arr.flat : <A, D extends number = 1>(this: A, depth?: D | undefined) => FlatArray<A, D>[]
> : ^ ^^ ^^^^^^^^^ ^^^^^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ function foo(arr, depth) {


//// [arrayFlatNoCrashInferenceDeclarations.d.ts]
declare function foo<T>(arr: T[], depth: number): FlatArray<T, 0 | 1 | -1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20>[];
declare function foo<T>(arr: T[], depth: number): FlatArray<T, -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20>[];
Loading