Skip to content

Commit

Permalink
Array.prototype.sort - remove the need for compareFn to handle undefi…
Browse files Browse the repository at this point in the history
…ned values. Fixes #41708
  • Loading branch information
Brookke committed Dec 30, 2020
1 parent 6907e36 commit 16d2047
Show file tree
Hide file tree
Showing 9 changed files with 23 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/lib/es5.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1257,7 +1257,7 @@ interface Array<T> {
* [11,2,22,1].sort((a, b) => a - b)
* ```
*/
sort(compareFn?: (a: T, b: T) => number): this;
sort(compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number): this;
/**
* Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
* @param start The zero-based location in the array from which to start removing elements.
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/implementArrayInterface.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ declare class MyArray<T> implements Array<T> {
reverse(): T[];
shift(): T;
slice(start?: number, end?: number): T[];
sort(compareFn?: (a: T, b: T) => number): this;
sort(compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number): this;
splice(start: number): T[];
splice(start: number, deleteCount: number, ...items: T[]): T[];
unshift(...items: T[]): number;
Expand Down
10 changes: 6 additions & 4 deletions tests/baselines/reference/implementArrayInterface.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,23 @@ declare class MyArray<T> implements Array<T> {
>end : Symbol(end, Decl(implementArrayInterface.ts, 10, 25))
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))

sort(compareFn?: (a: T, b: T) => number): this;
sort(compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number): this;
>sort : Symbol(MyArray.sort, Decl(implementArrayInterface.ts, 10, 45))
>compareFn : Symbol(compareFn, Decl(implementArrayInterface.ts, 11, 9))
>a : Symbol(a, Decl(implementArrayInterface.ts, 11, 22))
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))
>b : Symbol(b, Decl(implementArrayInterface.ts, 11, 27))
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))
>b : Symbol(b, Decl(implementArrayInterface.ts, 11, 57))
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))

splice(start: number): T[];
>splice : Symbol(MyArray.splice, Decl(implementArrayInterface.ts, 11, 51), Decl(implementArrayInterface.ts, 12, 31))
>splice : Symbol(MyArray.splice, Decl(implementArrayInterface.ts, 11, 111), Decl(implementArrayInterface.ts, 12, 31))
>start : Symbol(start, Decl(implementArrayInterface.ts, 12, 11))
>T : Symbol(T, Decl(implementArrayInterface.ts, 0, 22))

splice(start: number, deleteCount: number, ...items: T[]): T[];
>splice : Symbol(MyArray.splice, Decl(implementArrayInterface.ts, 11, 51), Decl(implementArrayInterface.ts, 12, 31))
>splice : Symbol(MyArray.splice, Decl(implementArrayInterface.ts, 11, 111), Decl(implementArrayInterface.ts, 12, 31))
>start : Symbol(start, Decl(implementArrayInterface.ts, 13, 11))
>deleteCount : Symbol(deleteCount, Decl(implementArrayInterface.ts, 13, 25))
>items : Symbol(items, Decl(implementArrayInterface.ts, 13, 46))
Expand Down
10 changes: 5 additions & 5 deletions tests/baselines/reference/implementArrayInterface.types
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ declare class MyArray<T> implements Array<T> {
>start : number
>end : number

sort(compareFn?: (a: T, b: T) => number): this;
>sort : (compareFn?: (a: T, b: T) => number) => this
>compareFn : (a: T, b: T) => number
>a : T
>b : T
sort(compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number): this;
>sort : (compareFn?: (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number) => this
>compareFn : (a: T extends undefined ? never : T, b: T extends undefined ? never : T) => number
>a : T extends undefined ? never : T
>b : T extends undefined ? never : T

splice(start: number): T[];
>splice : { (start: number): T[]; (start: number, deleteCount: number, ...items: T[]): T[]; }
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/restInvalidArgumentType.types
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function f<T extends { b: string }>(p1: T, p2: T[]) {
>p1 : T

var {...r2} = p2; // OK
>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; }
>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; }
>p2 : T[]

var {...r3} = t; // Error, generic type paramter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
({...[]} = {});
>({...[]} = {}) : {}
>{...[]} = {} : {}
>{...[]} : { [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; }
>{...[]} : { [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; }
>[] : undefined[]
>{} : {}

({...([])} = {});
>({...([])} = {}) : {}
>{...([])} = {} : {}
>{...([])} : { [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; }
>{...([])} : { [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; }
>([]) : undefined[]
>[] : undefined[]
>{} : {}
Expand Down
Loading

0 comments on commit 16d2047

Please sign in to comment.