Skip to content

Commit 16d2047

Browse files
committed
Array.prototype.sort - remove the need for compareFn to handle undefined values. Fixes #41708
1 parent 6907e36 commit 16d2047

9 files changed

+23
-21
lines changed

src/lib/es5.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,7 @@ interface Array<T> {
12571257
* [11,2,22,1].sort((a, b) => a - b)
12581258
* ```
12591259
*/
1260-
sort(compareFn?: (a: T, b: T) => number): this;
1260+
sort(compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number): this;
12611261
/**
12621262
* Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
12631263
* @param start The zero-based location in the array from which to start removing elements.

tests/baselines/reference/implementArrayInterface.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ declare class MyArray<T> implements Array<T> {
1010
reverse(): T[];
1111
shift(): T;
1212
slice(start?: number, end?: number): T[];
13-
sort(compareFn?: (a: T, b: T) => number): this;
13+
sort(compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number): this;
1414
splice(start: number): T[];
1515
splice(start: number, deleteCount: number, ...items: T[]): T[];
1616
unshift(...items: T[]): number;

tests/baselines/reference/implementArrayInterface.symbols

+6-4
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,23 @@ declare class MyArray<T> implements Array<T> {
5252
>end : Symbol(end, Decl(implementArrayInterface.ts, 10, 25))
5353
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))
5454

55-
sort(compareFn?: (a: T, b: T) => number): this;
55+
sort(compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number): this;
5656
>sort : Symbol(MyArray.sort, Decl(implementArrayInterface.ts, 10, 45))
5757
>compareFn : Symbol(compareFn, Decl(implementArrayInterface.ts, 11, 9))
5858
>a : Symbol(a, Decl(implementArrayInterface.ts, 11, 22))
5959
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))
60-
>b : Symbol(b, Decl(implementArrayInterface.ts, 11, 27))
60+
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))
61+
>b : Symbol(b, Decl(implementArrayInterface.ts, 11, 57))
62+
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))
6163
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))
6264

6365
splice(start: number): T[];
64-
>splice : Symbol(MyArray.splice, Decl(implementArrayInterface.ts, 11, 51), Decl(implementArrayInterface.ts, 12, 31))
66+
>splice : Symbol(MyArray.splice, Decl(implementArrayInterface.ts, 11, 111), Decl(implementArrayInterface.ts, 12, 31))
6567
>start : Symbol(start, Decl(implementArrayInterface.ts, 12, 11))
6668
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))
6769

6870
splice(start: number, deleteCount: number, ...items: T[]): T[];
69-
>splice : Symbol(MyArray.splice, Decl(implementArrayInterface.ts, 11, 51), Decl(implementArrayInterface.ts, 12, 31))
71+
>splice : Symbol(MyArray.splice, Decl(implementArrayInterface.ts, 11, 111), Decl(implementArrayInterface.ts, 12, 31))
7072
>start : Symbol(start, Decl(implementArrayInterface.ts, 13, 11))
7173
>deleteCount : Symbol(deleteCount, Decl(implementArrayInterface.ts, 13, 25))
7274
>items : Symbol(items, Decl(implementArrayInterface.ts, 13, 46))

tests/baselines/reference/implementArrayInterface.types

+5-5
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ declare class MyArray<T> implements Array<T> {
3838
>start : number
3939
>end : number
4040

41-
sort(compareFn?: (a: T, b: T) => number): this;
42-
>sort : (compareFn?: (a: T, b: T) => number) => this
43-
>compareFn : (a: T, b: T) => number
44-
>a : T
45-
>b : T
41+
sort(compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number): this;
42+
>sort : (compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number) => this
43+
>compareFn : (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number
44+
>a : T extends undefined ? never : T
45+
>b : T extends undefined ? never : T
4646

4747
splice(start: number): T[];
4848
>splice : { (start: number): T[]; (start: number, deleteCount: number, ...items: T[]): T[]; }

tests/baselines/reference/restInvalidArgumentType.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function f<T extends { b: string }>(p1: T, p2: T[]) {
7171
>p1 : T
7272

7373
var {...r2} = p2; // OK
74-
>r2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; pop(): T; push(...items: T[]): number; concat(...items: ConcatArray<T>[]): T[]; concat(...items: (T | ConcatArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean; some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
74+
>r2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; pop(): T; push(...items: T[]): number; concat(...items: ConcatArray<T>[]): T[]; concat(...items: (T | ConcatArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean; some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
7575
>p2 : T[]
7676

7777
var {...r3} = t; // Error, generic type paramter

tests/baselines/reference/restPropertyWithBindingPattern.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
({...[]} = {});
1818
>({...[]} = {}) : {}
1919
>{...[]} = {} : {}
20-
>{...[]} : { [n: number]: undefined; length: number; toString(): string; toLocaleString(): string; pop(): undefined; push(...items: undefined[]): number; concat(...items: ConcatArray<undefined>[]): undefined[]; concat(...items: ConcatArray<undefined>[]): undefined[]; join(separator?: string): string; reverse(): undefined[]; shift(): undefined; slice(start?: number, end?: number): undefined[]; sort(compareFn?: (a: undefined, b: undefined) => number): undefined[]; splice(start: number, deleteCount?: number): undefined[]; splice(start: number, deleteCount: number, ...items: undefined[]): undefined[]; unshift(...items: undefined[]): number; indexOf(searchElement: undefined, fromIndex?: number): number; lastIndexOf(searchElement: undefined, fromIndex?: number): number; every<S extends undefined>(predicate: (value: undefined, index: number, array: undefined[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): boolean; some(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): boolean; forEach(callbackfn: (value: undefined, index: number, array: undefined[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: undefined, index: number, array: undefined[]) => U, thisArg?: any): U[]; filter<S extends undefined>(predicate: (value: undefined, index: number, array: undefined[]) => value is S, thisArg?: any): S[]; filter(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): undefined[]; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduce<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduceRight<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; }
20+
>{...[]} : { [n: number]: undefined; length: number; toString(): string; toLocaleString(): string; pop(): undefined; push(...items: undefined[]): number; concat(...items: ConcatArray<undefined>[]): undefined[]; concat(...items: ConcatArray<undefined>[]): undefined[]; join(separator?: string): string; reverse(): undefined[]; shift(): undefined; slice(start?: number, end?: number): undefined[]; sort(compareFn?: (a: never, b: never) => number): undefined[]; splice(start: number, deleteCount?: number): undefined[]; splice(start: number, deleteCount: number, ...items: undefined[]): undefined[]; unshift(...items: undefined[]): number; indexOf(searchElement: undefined, fromIndex?: number): number; lastIndexOf(searchElement: undefined, fromIndex?: number): number; every<S extends undefined>(predicate: (value: undefined, index: number, array: undefined[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): boolean; some(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): boolean; forEach(callbackfn: (value: undefined, index: number, array: undefined[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: undefined, index: number, array: undefined[]) => U, thisArg?: any): U[]; filter<S extends undefined>(predicate: (value: undefined, index: number, array: undefined[]) => value is S, thisArg?: any): S[]; filter(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): undefined[]; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduce<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduceRight<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; }
2121
>[] : undefined[]
2222
>{} : {}
2323

2424
({...([])} = {});
2525
>({...([])} = {}) : {}
2626
>{...([])} = {} : {}
27-
>{...([])} : { [n: number]: undefined; length: number; toString(): string; toLocaleString(): string; pop(): undefined; push(...items: undefined[]): number; concat(...items: ConcatArray<undefined>[]): undefined[]; concat(...items: ConcatArray<undefined>[]): undefined[]; join(separator?: string): string; reverse(): undefined[]; shift(): undefined; slice(start?: number, end?: number): undefined[]; sort(compareFn?: (a: undefined, b: undefined) => number): undefined[]; splice(start: number, deleteCount?: number): undefined[]; splice(start: number, deleteCount: number, ...items: undefined[]): undefined[]; unshift(...items: undefined[]): number; indexOf(searchElement: undefined, fromIndex?: number): number; lastIndexOf(searchElement: undefined, fromIndex?: number): number; every<S extends undefined>(predicate: (value: undefined, index: number, array: undefined[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): boolean; some(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): boolean; forEach(callbackfn: (value: undefined, index: number, array: undefined[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: undefined, index: number, array: undefined[]) => U, thisArg?: any): U[]; filter<S extends undefined>(predicate: (value: undefined, index: number, array: undefined[]) => value is S, thisArg?: any): S[]; filter(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): undefined[]; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduce<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduceRight<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; }
27+
>{...([])} : { [n: number]: undefined; length: number; toString(): string; toLocaleString(): string; pop(): undefined; push(...items: undefined[]): number; concat(...items: ConcatArray<undefined>[]): undefined[]; concat(...items: ConcatArray<undefined>[]): undefined[]; join(separator?: string): string; reverse(): undefined[]; shift(): undefined; slice(start?: number, end?: number): undefined[]; sort(compareFn?: (a: never, b: never) => number): undefined[]; splice(start: number, deleteCount?: number): undefined[]; splice(start: number, deleteCount: number, ...items: undefined[]): undefined[]; unshift(...items: undefined[]): number; indexOf(searchElement: undefined, fromIndex?: number): number; lastIndexOf(searchElement: undefined, fromIndex?: number): number; every<S extends undefined>(predicate: (value: undefined, index: number, array: undefined[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): boolean; some(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): boolean; forEach(callbackfn: (value: undefined, index: number, array: undefined[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: undefined, index: number, array: undefined[]) => U, thisArg?: any): U[]; filter<S extends undefined>(predicate: (value: undefined, index: number, array: undefined[]) => value is S, thisArg?: any): S[]; filter(predicate: (value: undefined, index: number, array: undefined[]) => unknown, thisArg?: any): undefined[]; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduce<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduceRight<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; }
2828
>([]) : undefined[]
2929
>[] : undefined[]
3030
>{} : {}

0 commit comments

Comments
 (0)