drago.cc

A utility for null and undefined array filtering in TypeScript

The solution

export function notNullOrUndefined<TType>( item: TType | null | undefined, ): item is TType { return item !== null && item !== undefined; }

Example usage

const users: User[] = [ { name: "Anthony", website: "https://anthonysgoods.com" }, { name: "Pam" }, // Pam doesn't have a website ]; // ❌ The `Boolean` filter removes undefined values, but TypeScript doesn't // understand that const userWebsites: (string | undefined)[] = users .map((user) => user.website) .filter(Boolean); // ✅ The `notNullOrUndefined` filter achieves the same thing, but provides an // extra hint to TypeScript that no `undefined` will exist in the array const userWebsites: string[] = users .map((user) => user.website) .filter(notNullOrUndefined);

The problem

In TypeScript, it's common to transform an array of objects into an array containing a specific property from those objects, which may potentially be null or undefined. For instance, let's say we want to compile a list of our users' websites, but some users might not have a website.

We can start with an interface and an array of user objects:

interface User { name: string; website?: string; } const users: User[] = [ { name: "Anthony", website: "https://anthonysgoods.com" }, { name: "Pam" }, // Pam doesn't have a website ];

To create an array of their websites, we could initially attempt this:

const websites = users.map((user) => user.website);

However, this leads to the websites variable having the type (string | undefined)[], which isn't ideal.

Subsequently, you might try filtering out the undefined values:

const websites = users.map((user) => user.website).filter(Boolean);

Despite this, websites still remains of type (string | undefined)[].

This is where the notNullOrUndefined function proves useful:

export function notNullOrUndefined<TType>( item: TType | null | undefined, ): item is TType { return item !== null && item !== undefined; }

It checks whether the provided item is either null or undefined and provides TypeScript with a type hint, resulting in a cleaner and more precise string[]:

const websites = users.map((user) => user.website).filter(notNullOrUndefined);

In summary, the notNullOrUndefined function assists in filtering out null or undefined values when working with arrays of potentially nullable properties, leading to a more refined and expected data type.

Published: September 14, 2023 at 1:56 AM

Edited: September 16, 2023 at 1:51 PM