Narrowing arrow types with Array.filter and TypeScript

Mark Slade
1 min readMar 25, 2021

When dealing with heterogeneous arrays in TypeScript, I frequently want to use list.filter(...) to extract an array of all one type. However without extra effort, TypeScript will implicitly type the result of that filtering the same as the input.

For example:

Notice how numbers and strings are still considered heterogeneous by TypeScript, even though we know they’re not. It turns out Array.filter is a generic and can accept a type to narrow down to. Here’s how:

With this approach, reallyJustNumbers and reallyJustStrings are homogeneous arrays, which makes it easier to work with the items in them.

The key to this approach is two parts:

  1. Using filter<type> to specify the type we’re narrowing down to.
  2. Defining the filter function as a user defined type guard using (thing): thing is number .

When we define the function’s return type as thing is number we’re telling TypeScript that the returned value will be a boolean that indicates whether or not the parameter thing is of type number . The logic within our filter function hasn’t changed — it’s just that we’ve given the compiler the information it needs to know that the filter narrows the input type down to just numbers.

User defined type guards are basically awesome. You can read more about them in my article on type guards and user input validation:

--

--

Mark Slade

Full stack web developer, typescript evangelist, human