msqar
msqar

Reputation: 3020

Narrow down a type of an object property within filter & map chain in TypeScript

I'm trying to narrow and type guard a property of an specific object while filtering and mapping but I'm not fully understanding how to do it.

Let's say I got the following array of Objects of interface Person:

interface IPerson {
   name: string;
   age: number;
   height: number | null;
}

const personArray: IPerson[] = [...]

Let's say I would like to filter those that aren't null first and then map the result and do something with those filtered out.

personArray
   .filter((person) => person.height !== null)
   .map((person) => this.doSomethingAboutIt(person.height))

The doSomethingAboutIt function expects a number only, not a null. That's why I wanted to filter non-null first. But TypeScripts shows an error saying that doSomethingAboutIt is expecting a number, and not a number | null. Even thought there shouldn't be any null during the map function. Of course TypeScript doesn't know this yet. I thought it would be automatically inferred but I was wrong.

How can I narrow down the type to only number on object properties?

Thanks.

Upvotes: 3

Views: 1530

Answers (1)

moustafa
moustafa

Reputation: 271

You need to use type guard as follows:

interface IPerson {
    name: string;
    age: number;
    height: number | null;
}

const doSomethingAboutIt = (h: number) => {};

const personArray: IPerson[] = [];
personArray
    .filter((person): person is IPerson & { height: number } => person.height !== null)
    .map((person) => doSomethingAboutIt(person.height));

Upvotes: 5

Related Questions