Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript filter out nulls from an array

People also ask

How do you filter null values in an array?

To remove all null values from an array:Use the Array. filter() method to iterate over the array. Check if each element is not equal to null . The filter() method returns a new array containing only the elements that satisfy the condition.

How do you filter out null?

The most common filter syntax to filter out nulls is simply "-NULL" . This works for most data types that aren't numbers, such as strings, dates, etc.

Is there null in TypeScript?

TypeScript has two special types, Null and Undefined, that have the values null and undefined respectively.


You can use a type predicate function in the .filter to avoid opting out of strict type checking:

function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
    return value !== null && value !== undefined;
}

const array: (string | null)[] = ['foo', 'bar', null, 'zoo', null];
const filteredArray: string[] = array.filter(notEmpty);

Alternatively you can use array.reduce<string[]>(...).

2021 update: stricter predicates

While this solution works in most scenarios, you can get a more rigorous type check in the predicate. As presented, the function notEmpty does not actually guarantee that it identifies correctly whether the value is null or undefined at compile time. For example, try shortening its return statement down to return value !== null;, and you'll see no compiler error, even though the function will incorrectly return true on undefined.

One way to mitigate this is to constrain the type first using control flow blocks, and then to use a dummy variable to give the compiler something to check. In the example below, the compiler is able to infer that the value parameter cannot be a null or undefined by the time it gets to the assignment. However, if you remove || value === undefined from the if condition, you will see a compiler error, informing you of the bug in the example above.

function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
  if (value === null || value === undefined) return false;
  const testDummy: TValue = value;
  return true;
}

A word of caution: there exist situations where this method can still fail you. Be sure to be mindful of issues associated with contravariance.


Similar to @bijou-trouvaille's answer, you just need to declare the <arg> is <Type> as the output of the filter function:

array.filter((x): x is MyType => x !== null);

One more for good measure as people often forget about flatMap which can handle filter and map in one go (this also doesn't require any casting to string[]):

// (string | null)[]
const arr = ["a", null, "b", "c"];
// string[]
const stringsOnly = arr.flatMap(f => f ? [f] : []);

You can cast your filter result into the type you want:

const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray = array.filter(x => x != null) as string[];

This works for the more general use case that you mentioned, for example:

const array2: (string | number)[] = ["str1", 1, "str2", 2];
const onlyStrings = array2.filter(x => typeof x === "string") as string[];
const onlyNumbers = array2.filter(x => typeof x === "number") as number[];

(code in playground)