Skip to content

Type guards in Array.prototype.every #14963

Description

@kylewlacy

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)

Activity

  1. vkurchatkin commented on Apr 1, 2017

    @vkurchatkin
    Contributor

    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.

  2. kylewlacy commented on Apr 2, 2017

    @kylewlacy
    Author

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

  3. vkurchatkin commented on Apr 3, 2017

    @vkurchatkin
    Contributor

    Kyle Lacy (@kylewlacy) yes, I think so

  4. added 4 commits that reference this issue on Sep 10, 2017
    537999c
    f8887c1
    cadf438
    e5a85e7
  5. added 2 commits that reference this issue on Sep 18, 2017
    ffd2d13
    fc29212
  6. added this to the milestone on Jan 4, 2018
  7. mhegazy commented on May 2, 2018

    @mhegazy
    Contributor

    related to #5101

  8. mhegazy commented on May 2, 2018

    @mhegazy
    Contributor

    #16069 now tracks inferring the type guard automatically.

  9. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDomain: lib.d.tsThe issue relates to the different libraries shipped with TypeScriptHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions