DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Chris
Chris

Posted on

How To Filter Values Type-Safely in TypeScript

TypeScript doesn't infer the return type of an array filter operation in the same way that it does for an if statement to check whether a variable is defined.

Let's consider the following example:

type User = {
  id: number;
  name?: string;
};

const listUsers = (): User[] => {
  // fetch users from some API and return them
  return [];
};

// names will be of type (string | undefined)[]
const names = listUsers()
  .map((user) => user.name)
  .filter((name) => !!name);
Enter fullscreen mode Exit fullscreen mode

The type of names is inferred by TypeScript as (string | undefined)[], although we explicitly filter out falsy values. TypeScript somehow doesn't interpret the condition inside the filter function.

To get TypeScript to infer the return type correctly, we need to use a custom type-guard.

// type-guard to assure name is a string
const filterNames = (name?: string): name is string => {
  return !!name;
}

const names = listUsers()
  .map((user) => user.name)
  .filter(filterNames);
Enter fullscreen mode Exit fullscreen mode

The return type name is string of this type-guard function will assure TypeScript that we have checked the type and can safely treat it as string.

However, if we don't want to define a separate filter function, we can also use the type guard inside the inline filter function:

const names = listUsers()
  .map((user) => user.name)
  .filter((name?: string): name is string => !!name);
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
niklampe profile image
Nik

Great article. πŸ™Œ Needed to solve a similar problem just now.

Hi!I'm Noah!

Hey, my name is Noah and I’m the one who set up this ad!


My job is to get you to join DEV, so if you fancy doing me a favor, I’d love for you to create an account.
Β 
If you found DEV from searching around, here are a couple of our most popular articles on DEV: