TypeScript Exclude, Extract and NonNullable
Exclude, Extract and NonNullable filter an existing union instead of rebuilding it by hand. Each utility returns a new union built from the members that pass its filter.
Exclude drops members
Exclude removes the named members from a union. The members that remain form the new type.
type Route = 'home' | 'about' | 'admin' | 'settings';
type PublicRoute = Exclude<Route, 'admin' | 'settings'>;
const first: PublicRoute = 'home';
const second: PublicRoute = 'about';
console.log(first);
console.log(second);Extract keeps shared members
Extract keeps only the members that appear in both unions. Every other member drops out.
type Mixed = string | number | boolean | null;
type TextOrCount = Extract<Mixed, string | number>;
const label: TextOrCount = 'ready';
const count: TextOrCount = 3;
console.log(label);
console.log(count);NonNullable removes null and undefined
NonNullable strips null and undefined from a union. The remaining members keep their original types.
type MaybeId = number | null | undefined;
type SureId = NonNullable<MaybeId>;
const ids: SureId[] = [101, 102];
console.log(ids.join(', '));A removed value is refused
The filtered type no longer contains the admin member. Assigning that member fails at compile time.
type Route = 'home' | 'about' | 'admin';
type PublicRoute = Exclude<Route, 'admin'>;
const page: PublicRoute = 'admin';
console.log(page);Example
type ShapeName = 'circle' | 'square' | 'triangle' | null;
type RealShape = NonNullable<ShapeName>;
type RoundShape = Extract<RealShape, 'circle' | 'oval'>;
type FlatShape = Exclude<RealShape, 'circle'>;
const roundOne: RoundShape = 'circle';
const flatOne: FlatShape = 'square';
console.log(roundOne);
console.log(flatOne);Key points
- Exclude<T, U> removes every member of T that matches U.
- Extract<T, U> keeps only the members of T that also appear in U.
- NonNullable<T> removes null and undefined from T.
- Each result is an ordinary union type that variables and parameters can use directly.
- The filtered union is stated twice in this lesson because filtering is the whole pattern.
- A value removed by a filter is refused with the same error as any other wrong literal.
In this example, NonNullable removes null first, then Extract keeps the one round member and Exclude builds the flat set from what remains.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท TypeScript Playground
Exercise
What type does Exclude<'a' | 'b' | 'c', 'b'> produce?