Skip to content

Commit cadf438

Browse files
committed
Added overload to ReadonlyArray.prototype.every to make it a type guard if the callback is one.
Also made the type of thisArg generic. Fixes microsoft#14963
1 parent eb80799 commit cadf438

File tree

4 files changed

+81
-0
lines changed

4 files changed

+81
-0
lines changed

src/lib/es5.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,7 @@ interface ReadonlyArray<T> {
10141014
* @param callbackfn A function that accepts up to three arguments. The every method calls the callbackfn function for each element in array1 until the callbackfn returns false, or until the end of the array.
10151015
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
10161016
*/
1017+
every<U extends T>(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => value is U, thisArg?: any): this is ReadonlyArray<U>;
10171018
every(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => boolean, thisArg?: any): boolean;
10181019
/**
10191020
* Determines whether the specified callback function returns true for any element of an array.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
tests/cases/compiler/arrayEvery.ts(15,9): error TS2322: Type 'ReadonlyArray<string | number>' is not assignable to type 'ReadonlyArray<number>'.
2+
Type 'string | number' is not assignable to type 'number'.
3+
Type 'string' is not assignable to type 'number'.
4+
5+
6+
==== tests/cases/compiler/arrayEvery.ts (1 errors) ====
7+
declare const baseReadonlyArray: ReadonlyArray<number | string>;
8+
9+
baseReadonlyArray.every(function (x) {
10+
return this.indexOf("f") > 0;
11+
}, "foo"); // first overload
12+
baseReadonlyArray.every(function (x) {
13+
return this.indexOf("f") > 0;
14+
}, 1); // error: thisArg type doesn't match
15+
16+
if (baseReadonlyArray.every<number>((x): x is number => "number" === typeof x)) {
17+
const numberReadonlyArray: ReadonlyArray<number> = baseReadonlyArray; // should be ReadonlyArray<number>
18+
}
19+
20+
if (baseReadonlyArray.every((x): x is number => "number" === typeof x)) {
21+
const numberReadonlyArray: ReadonlyArray<number> = baseReadonlyArray; // should be ReadonlyArray<number>
22+
~~~~~~~~~~~~~~~~~~~
23+
!!! error TS2322: Type 'ReadonlyArray<string | number>' is not assignable to type 'ReadonlyArray<number>'.
24+
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
25+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
26+
}
27+
28+
baseReadonlyArray.every(x => "number" === typeof x && x > 2);
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//// [arrayEvery.ts]
2+
declare const baseReadonlyArray: ReadonlyArray<number | string>;
3+
4+
baseReadonlyArray.every(function (x) {
5+
return this.indexOf("f") > 0;
6+
}, "foo"); // first overload
7+
baseReadonlyArray.every(function (x) {
8+
return this.indexOf("f") > 0;
9+
}, 1); // error: thisArg type doesn't match
10+
11+
if (baseReadonlyArray.every<number>((x): x is number => "number" === typeof x)) {
12+
const numberReadonlyArray: ReadonlyArray<number> = baseReadonlyArray; // should be ReadonlyArray<number>
13+
}
14+
15+
if (baseReadonlyArray.every((x): x is number => "number" === typeof x)) {
16+
const numberReadonlyArray: ReadonlyArray<number> = baseReadonlyArray; // should be ReadonlyArray<number>
17+
}
18+
19+
baseReadonlyArray.every(x => "number" === typeof x && x > 2);
20+
21+
//// [arrayEvery.js]
22+
baseReadonlyArray.every(function (x) {
23+
return this.indexOf("f") > 0;
24+
}, "foo"); // first overload
25+
baseReadonlyArray.every(function (x) {
26+
return this.indexOf("f") > 0;
27+
}, 1); // error: thisArg type doesn't match
28+
if (baseReadonlyArray.every(function (x) { return "number" === typeof x; })) {
29+
var numberReadonlyArray = baseReadonlyArray; // should be ReadonlyArray<number>
30+
}
31+
if (baseReadonlyArray.every(function (x) { return "number" === typeof x; })) {
32+
var numberReadonlyArray = baseReadonlyArray; // should be ReadonlyArray<number>
33+
}
34+
baseReadonlyArray.every(function (x) { return "number" === typeof x && x > 2; });

tests/cases/compiler/arrayEvery.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
declare const baseReadonlyArray: ReadonlyArray<number | string>;
2+
3+
baseReadonlyArray.every(function (x) {
4+
return this.indexOf("f") > 0;
5+
}, "foo"); // first overload
6+
baseReadonlyArray.every(function (x) {
7+
return this.indexOf("f") > 0;
8+
}, 1); // error: thisArg type doesn't match
9+
10+
if (baseReadonlyArray.every<number>((x): x is number => "number" === typeof x)) {
11+
const numberReadonlyArray: ReadonlyArray<number> = baseReadonlyArray; // should be ReadonlyArray<number>
12+
}
13+
14+
if (baseReadonlyArray.every((x): x is number => "number" === typeof x)) {
15+
const numberReadonlyArray: ReadonlyArray<number> = baseReadonlyArray; // should be ReadonlyArray<number>
16+
}
17+
18+
baseReadonlyArray.every(x => "number" === typeof x && x > 2);

0 commit comments

Comments
 (0)