What does NonNullable do, and when would you use it?
NonNullable<T> removes null and undefined from a type, so NonNullable<string | null | undefined> is string. It is useful after you have checked a value, or to type something that must never be empty.
Explain it simply
Imagine a form where phone may be missing. After validation you pass it to a function that needs a real value. NonNullable describes that "after the check" version of the type.
It only changes the type. It does not check anything at runtime, so it must follow actual validation. It also combines well with Array.prototype.filter and mapped types, for example removing optionality from every field.
Example
type MaybePhone = string | null | undefined;
type Phone = NonNullable<MaybePhone>; // string
function send(phone: NonNullable<MaybePhone>) {
console.log(phone.length);
}
const p: MaybePhone = "98765";
if (p != null) send(p); // narrowed to string, accepted
// Strip null/undefined from every property
type Clean<T> = { [K in keyof T]: NonNullable<T[K]> };
type Raw = { a: string | null; b?: number };
type Checked = Clean<Raw>;
// { a: string; b?: number } (the ? modifier is kept by the homomorphic mapping)What to say in the interview
"NonNullable<T> filters null and undefined out of a union. I use it for function parameters that must be present, after I have validated the input. It is purely a type-level change, so the validation still has to happen in real code."
Common mistakes
- Treating NonNullable as a runtime check; it does nothing when the code runs.