Exclude<T, U> is a utility type introduced in TypeScript to subtract one type from another, when certain values need to be excluded from a union type.
Originally, TypeScript did not have an easy way to subtract one type from another. When creating generic APIs and during refactoring, it was often required to obtain a "remaining" type — everything except prohibited values. Instead of manually manipulating unions, it was necessary to maintain several similar interfaces.
For example, when you have a type A | B | C, but you need to get the type without B. This is often required when building complex function parameter types, filtering allowed values, and dynamically forming types.
Exclude solves this problem. Its simplified signature is as follows:
type Exclude<T, U> = T extends U ? never : T;
It returns a type that excludes all members of U from T.
Example:
type Status = 'draft' | 'published' | 'removed'; type UserVisibleStatus = Exclude<Status, 'removed'>; const visible: UserVisibleStatus = 'draft'; // OK
Key features:
switch cases or object keys.Can Exclude be used for regular types, not just unions?
If T is not a union type but is part of U — Exclude will work nonetheless, but the result may be never or T, which is not always intuitive.
Exclude<'a', 'a'> // result: never Exclude<'a', 'b'> // result: 'a'
Does Exclude remove all mentions of the type in the object's structure?
No, Exclude does not recursively traverse nested fields of the type; it only excludes at the top level of the union.
How does Exclude work with interfaces and object types?
It compares the entire type, not individual properties. Therefore, Exclude from a union of several interfaces only removes those that match U completely.
interface A { x: number }; interface B { y: string }; // Exclude<A|B, B> gives: A (B matches completely)
never with complete type matches.Validating user roles through Exclude<UserRoles, 'admin'>, but forgetting that Exclude does not apply to nested structures — permissions 'admin:sub' were not excluded.
Pros:
Cons:
Using Exclude to restrict the public API actions: Exclude<Action, 'delete'>, which excludes a dangerous operation.
Pros:
Cons: