NonNullable<Type>
INFO
The NonNullable<Type>
utility type is available starting from TypeScript version 2.8. For more information see in TypeScript Handbook, Release Note.
Overview
The NonNullable<Type>
is a built in utility type in TypeScript that constructs a type by excluding null
and undefined
from Type
. This feature is particulary useful in situations where developers need to ensure that a variable will always have a value, thus eliminating the uncertainly associated with nullable types.
Syntax
ts
type NonNullable<T> = T extends null | undefiend ? never : T;
- Type (T): This represents a type from which you want to exclude
null
andundefined
.
Examples
Example #1
ts
type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string | string[] | null | undefined>; // string | string[]
type T2 = NonNullable<string | string[] | null>; // string | string[]
Example #2
ts
function isNotNullish<T>(value: T): value is NonNullable<T> {
return value !== null && value !== undefined;
}
Example #3
ts
type FulfilledForm<T> = { [K in keyof T]: NonNullable<T[K]> };
function isFullyFilled<T extends object>(form: T): form is FulfilledForm<T> {
return Object.values(form).every(value => value !== null && value !== undefined);
}
interface RecruitForm {
name: string | null;
age: number | null;
role: 'admin' | 'editor' | 'viewer' | null;
hobby: string[] | null;
university: string | null;
}
class EmployeeApiService {
private static readonly API_URL = '/api/employee';
async create(form: FulfilledForm<RecruitForm>): Promise<void> {
// Implementation will create employee
}
async recruit(form: RecruitForm): Promise<void> {
// The isFullyFilled returns true if and only if all fields in the form are neither null nor undefined.
// Therefore, after this function call, TypeScript infers the type of form as FulfilledForm<RecuritForm>.
if (isFullyFilled(form)) {
// TypeScript infers the type of form here as FulfilledForm<RecruitForm>.
// This means that all fields in form are guaranteed to have non-null and non-undefined values.
try {
await this.create(form);
} catch (error) {
// Error handling needed.
}
} else {
// In this block, TypeScript still infers the type of form as RecruitForm.
// This means that form could still contain null or undefined values in some of its fields.
// This block should handle cases where the form is incomplete.
}
}
}