Typescript: Type guards in Array.prototype.every

Created on 1 Apr 2017  路  5Comments  路  Source: microsoft/TypeScript

TypeScript Version: 2.2.2

Code

function isNumber(x: any): x is number { return typeof(x) === "number"; }

let numbersOrStrings: (number | string)[] = [1, 2, 3, 4];

if(numbersOrStrings.every(isNumber)) {
    let _numbers: number[] = numbersOrStrings;
    // ...
}

Expected behavior:

When every member of numberOfStrings matches the isNumber type guard, the whole array should be inferred to be numberOfStrings: number[]; so, the above code should compile without error.

Actual behavior:

The above fails to compile, with the following error:

error TS2322: Type '(string | number)[]' is not assignable to type 'number[]'.

This issue is similar to #7657, and it can be solved by adding something like the following to lib.d.ts:

interface Array<T> {
    every<U extends T>(pred: (a: T) => a is U): this is U[];
}

(or, the above can be added locally to a project as a temporary workaround)

Bug lib.d.ts help wanted

Most helpful comment

This issue is similar to #7657,

It's not the same, though. filter creates a new array, every doesn't. Assigning (string | number)[] to a number[] is unsafe, because a string can be pushed at any moment.

All 5 comments

This issue is similar to #7657,

It's not the same, though. filter creates a new array, every doesn't. Assigning (string | number)[] to a number[] is unsafe, because a string can be pushed at any moment.

@vkurchatkin Would adding the above declaration for ReadonlyArray<T> be safe, then?

@kylewlacy yes, I think so

16069 now tracks inferring the type guard automatically.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zhuravlikjb picture zhuravlikjb  路  3Comments

remojansen picture remojansen  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments

blendsdk picture blendsdk  路  3Comments

MartynasZilinskas picture MartynasZilinskas  路  3Comments