Skip to content

"Number.isFinite" and "Number.isInteger" do not filter out values as a predicate #39090

Closed

Description

TypeScript Version: 3.9.2

Search Terms: isFinite, isInteger, filter, callback, predicate, null values

Code

const nums = [1, 2, 3, null, 5];
const filteredFinite = nums.filter(Number.isFinite);
const filteredIntegers = nums.filter(Number.isInteger);

Expected behavior:

const filteredFinite: number[]
const filteredIntegers: number[]

Actual behavior:

const filteredFinite: (number | null)[]
const filteredIntegers: (number | null)[]

Playground Link:
https://www.typescriptlang.org/play/?ssl=2&ssc=7&pln=2&pc=21#code/MYewdgzgLgBGCuBbCMC8MDaBGANDATHgMx4IA2ZeArALoDcAsAFCiSwBmAlmVAKYBOvACYAxTmE580cJBAB0XHgIAUAOSQAjAXM4QxEvgEpGLcNBiK+goQEkwfAOYCU6BMgXcrazdt13HAsbMzKwQIGS8cmQgDsqWAsL6krxBppDhkdGx8db+vE78EKlAA

Related Issues: not found

Activity

  1. fatcerberus commented on Jun 16, 2020

    @fatcerberus

    As far as TS is concerned, it's just like any other function, a black box that returns true or false. There's no special case in the compiler that says using Number.isFinite in particular will remove all the nulls.

    edit: I forgot type predicates are a thing, ignore the above brainfart.

    Note that the function doesn't work as a type predicate in general either:

    let x: number | null = 777 as any;
    if (Number.isFinite(x)) {
        x;  // still number | null
    }

    The fix would be for these functions to be declared as predicates, e.g.

        isFinite(number: unknown): number is number;
  2. RyanCavanaugh commented on Jun 16, 2020

    @RyanCavanaugh
    Member

    Type guards are only correctly type guards if they return true for every value of the tested type, not some values of the type.

    See #15048 for supporting type guards that only identify a subset of their type.

  3. fatcerberus commented on Jun 16, 2020

    @fatcerberus

    Ah right, because otherwise !Number.isInteger(x) implies that x is not a number and would be narrowed as such. I forgot that that works both ways when I made the above suggestion.

  4. typescript-bot commented on Jun 18, 2020

    @typescript-bot
    Contributor

    This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  5. 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

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions