TypeScript NonNullable<T> Utility Type Explained
Learn how NonNullable<T> removes null and undefined from a type. Practical examples for strict null checks and type narrowing.
Union Types
Detailed Explanation
Understanding NonNullable
NonNullable<T> constructs a type by excluding null and undefined from T. It is a specialized form of Exclude.
Syntax
type NonNullable<T> = Exclude<T, null | undefined>;
// Equivalent to:
type NonNullable<T> = T & {};
Basic Example
type MaybeString = string | null | undefined;
type DefiniteString = NonNullable<MaybeString>;
// Result: string
type Mixed = string | number | null | undefined | boolean;
type NonNullMixed = NonNullable<Mixed>;
// Result: string | number | boolean
Practical Pattern: After Null Checks
function processValue<T>(value: T | null | undefined): NonNullable<T> {
if (value == null) {
throw new Error("Value is required");
}
return value as NonNullable<T>;
}
With Array.filter()
A common pattern is filtering out null values from arrays:
const items: (string | null)[] = ["a", null, "b", null, "c"];
// Without NonNullable -- TypeScript still thinks nulls might exist
const filtered = items.filter((x) => x !== null);
// Type: (string | null)[]
// With NonNullable type predicate
const safe = items.filter(
(x): x is NonNullable<typeof x> => x !== null
);
// Type: string[]
In Mapped Types
type RequiredNonNull<T> = {
[K in keyof T]-?: NonNullable<T[K]>;
};
Use Case
Use NonNullable<T> when working with strictNullChecks enabled and you need to assert that a value has been validated as non-null. Common in validation layers, array filtering, and after guard clauses.