Last updated: Feb 28, 2024
Reading timeยท2 min
Use the NonNullable
utility type to remove null
and undefined
from a
type in TypeScript.
The NonNullable
utility type constructs a new type with null
and
undefined
excluded from the type.
type Salary = null | undefined | number; // ๐๏ธ type T0 = number type T0 = NonNullable<Salary>;
The
NonNullable
utility type excludes null
and undefined
from the passed-in type.
type Name = null | undefined | string; // ๐๏ธ type T2 = string type T2 = NonNullable<Name>;
The union in the example consists
of null
, undefined
and string
.
Once passed to the NonNullable
utility type, the result only has a type of
string
.
All of the non-nullable types are preserved in the result.
type Employees = null | undefined | string | string[]; // ๐๏ธ type T2 = string | string[] type T2 = NonNullable<Employees>;
NonNullable
type recursivelyHowever, in some situations, you might need to use the NonNullable
type
recursively, to make all of the keys in a type non-nullable.
type WithoutNullableKeys<Type> = { [Key in keyof Type]-?: WithoutNullableKeys<NonNullable<Type[Key]>>; }; type Employee = { name?: string | null; country?: string | null; salary?: number | null; }; // ๐๏ธ type T1 = { // name: string; // country: string; // salary: number; // } type T1 = WithoutNullableKeys<Employee>;
The -?
syntax is called a
mapping modifier
and is used to set the attributes of a type to required (remove optionality).
type Employee = { name?: string | null; country?: string | null; salary?: number | null; }; type Concrete<Type> = { [Key in keyof Type]-?: Type[Key]; }; // ๐๏ธ type T2 = { // name: string | null; // country: string | null; // salary: number | null; // } type T2 = Concrete<Employee>;
The example shows how the Concrete
type makes all of the keys in Employee
required.
This approach can also be used to remove null
and undefined
from an
interface.
type WithoutNullableKeys<Type> = { [Key in keyof Type]-?: WithoutNullableKeys<NonNullable<Type[Key]>>; }; interface Employee { name?: string | null; country?: string | null; salary?: number | null; } // ๐๏ธ type T1 = { // name: string; // country: string; // salary: number; // } type T1 = WithoutNullableKeys<Employee>;
I've also written an article on how to set a default value if null or undefined in TS.
You can learn more about the related topics by checking out the following tutorials: