What is TypeScript Exclude?
The Exclude utility type in TypeScript is used to create a type by excluding certain types from another type.
It’s like filtering out some types from a given type.
Here’s the syntax for Exclude:
type Exclude = T extends U ? never : T;In this syntax, T is the original type, and U is the type you want to exclude from T. The extends keyword is used to check if T is assignable to U.
If it is, never is returned, effectively excluding it. If not, T is returned.
Let’s see an example:
type T1 = Exclude<"x" | "y" | "z", "x">;
// Result: "y" | "z"In this example, the type "x" is excluded from the union type "x" | "y" | "z", resulting in the type "y" | "z".
Moreover, the Exclude utility type is used to construct a type by excluding certain types from a union. It allows developers to remove specific types from a union type, making it easier to work with subsets of types.
The Exclude type is particularly useful when dealing with large and complex type unions, as it provides a way to simplify type definitions and ensure type safety.
How to use Exclude in TypeScript?
Here’s the step-by-step guide in order to use Exclude in TypeScript.
Step 1:
Define your original type.This could be an object type representing an employee:
type Employee = {
name: string;
age: number;
position: string;
salary: number;
};Step 2:
Decide which properties you want to exclude from your original type. In this case, let’s say we want to exclude salary.
Step 3:
Use the Exclude utility type to create a new type that excludes the specified properties from the original type.
Here’s how you do it:
type PublicEmployee = {
};Now, PublicEmployee is a type that includes name, age, and position, but not salary.
Step 4:
You can now use PublicEmployee in your code just like any other type.
For example, you can create a function that takes a PublicEmployee as an argument:
function printEmployeeDetails(employee: PublicEmployee) {
console.log(Name: ${employee.name});
console.log(Age: ${employee.age});
console.log(Position: ${employee.position});
}This function will print the details of an employee, excluding the salary.
10 Ways to Use Exclude in TypeScript with Examples
Here are the 10 ways to use Exclude in TypeScript with examples.
- Exclude Specific Types from Union Types:
type SampleSubject = "Programming" | "Software Development" | "Web Development";
type NewType = Exclude<SampleSubject, "Programming" | "Software Development">;
// Result: "Web Development"- Exclude Number Types from Union Types:
type MixedType = string | number | boolean;
type NoNumbers = Exclude; // Result: string | boolean- Exclude Specific Object Properties:
type Employee = {
name: string;
age: number;
salary: number;
};
type PublicEmployee = {
}; // Result: { name: string; age: number; }- Exclude Null and Undefined Types:
type NullableType = string | null | undefined;
type NonNullableType = Exclude; // Result: string- Exclude Specific Enum Members:
enum Colors {
Red,
Green,
Blue
}
type PrimaryColors = Exclude; // Result: Colors.Red | Colors.Blue- Exclude Specific Classes:
class Circle { /* … / } class Square { / … */ }
type Shape = Circle | Square;
type NonSquareShapes = Exclude; // Result: Circle- Exclude Types from Any:
type NotBoolean = Exclude; // Result: any except boolean- Exclude Types from Unknown:
type NotNumber = Exclude; // Result: unknown except number- Exclude Function Types:
type MixedType = string | (() => void);
type NoFunctions = Exclude void>; // Result: string- Exclude Array Types:
type MixedType = string | string[];
type NoArrays = Exclude; // Result: stringThose are the 10 different ways to use Exclude in TypeScript.
The examples show how the Exclude utility type can be used to create new types by excluding specific types from existing ones.
Exclude vs Other TypeScript Utility Types
Exclude is one of five utility types that operate on union types. Knowing when to use each is more valuable than just knowing Exclude alone:
| Utility | What It Does | Example |
|---|---|---|
Exclude<T, U> | Removes types in U from T (union) | Exclude<"a"|"b"|"c", "a"> → "b"|"c" |
Extract<T, U> | Keeps only types in T that are assignable to U | Extract<"a"|1|"b", string> → "a"|"b" |
Omit<T, K> | Removes properties K from object T | Omit<User, "password"> |
Pick<T, K> | Keeps only properties K from object T | Pick<User, "id"|"email"> |
NonNullable<T> | Removes null and undefined from T | NonNullable<string|null> → string |
Rule of thumb:Use Exclude/Extract for union types (string literals, primitives); use Omit/Pick for object types (properties).
Real-World Exclude Patterns
Pattern 1: Restricting HTTP Methods
type AllMethods = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
type ReadOnlyMethods = Exclude<AllMethods, "POST" | "PUT" | "DELETE" | "PATCH">;
// ReadOnlyMethods is now: "GET"
function safeRequest(method: ReadOnlyMethods, url: string) {
// Only GET requests allowed here
return fetch(url, { method });
}Pattern 2: Filtering Event Types
type AppEvent = "user.login" | "user.logout" | "admin.delete" | "admin.create";
type UserEvents = Exclude<AppEvent, `admin.${string}`>;
// UserEvents is now: "user.login" | "user.logout"
function trackUserEvent(event: UserEvents) {
analytics.track(event);
}
// trackUserEvent("admin.delete"); // ❌ Compile errorPattern 3: Removing Functions From a Type
type Mixed = string | number | (() => void) | boolean;
type DataOnly = Exclude<Mixed, Function>;
// DataOnly is now: string | number | boolean
function serialize(value: DataOnly): string {
return JSON.stringify(value);
}
// serialize(() => {}); // ❌ Functions not allowedCommon Mistakes With Exclude
- Using Exclude on object types.
Excludeonly filters union types. For object types (interfaces, classes), useOmitinstead. - Confusing Exclude with Extract.Exclude REMOVES; Extract KEEPS.
Exclude<A, B>gives you “A but not B”;Extract<A, B>gives you “the intersection of A and B”. - Forgetting that Exclude is structural, not nominal.If two types are structurally identical, Exclude treats them as the same type and removes both, even if you named them differently.
- Trying to Exclude based on a runtime value.Exclude only works at compile time on TYPES, not on values. You can’t write
Exclude<myArray, "specificString">at runtime. - Over-using Exclude where a simpler union would do.If your union is small and known, just write it out:
type Read = "GET"is clearer thanExclude<AllMethods, "POST"|"PUT"|"DELETE"|"PATCH">.
Conclusion
Finally, we’re done discussing the Exclude utility type in TypeScript, which is used to create new types by excluding specific types from existing ones.
It’s like filtering out some types from a given type, which can simplify type definitions and ensure type safety, especially when dealing with large and complex type unions.
We’ve also explored the different ways to use the Exclude utility type in TypeScript, along with examples.
These examples demonstrate the versatility and usefulness of the Exclude utility type in TypeScript.
By understanding and utilizing this utility type, developers can write more efficient and safer TypeScript code.
I hope this article has given you some insights and helped you understand the TypeScript Record.
If you have any questions or inquiries, please don’t hesitate to leave a comment below.
Frequently Asked Questions
What is Exclude in TypeScript?
Exclude is a built-in TypeScript utility type that creates a new type by REMOVING members from a union type. Syntax: Exclude<T, U> takes a union T and removes any types in T that are also in U. For example, Exclude<"a" | "b" | "c", "a"> produces the type "b" | "c". It only works on union types, for filtering object properties, use Omit instead.
What’s the difference between Exclude and Omit in TypeScript?
Exclude works on UNION types (string literals, primitives), it removes union members. Omit works on OBJECT types (interfaces, classes), it removes properties. Exclude<"a"|"b", "a"> → "b". Omit<{a: string, b: number}, "a"> → {b: number}. Don’t mix them up, using Exclude on an object type returns the entire object unchanged.
What’s the difference between Exclude and Extract in TypeScript?
They are opposites. Exclude REMOVES; Extract KEEPS. Exclude<"a"|"b"|"c", "a"> returns "b" | "c". Extract<"a"|"b"|"c", "a"> returns "a". Use Exclude when you want everything EXCEPT certain values; use Extract when you want ONLY certain values.
Can I use Exclude with template literal types?
Yes, TypeScript 4.1+ supports this. For example: Exclude<"user.login" | "user.logout" | "admin.delete", `admin.${string}`> removes all event names that start with “admin.” and returns "user.login" | "user.logout". This is one of the most powerful uses of Exclude in modern TypeScript codebases.
Is Exclude evaluated at compile time or runtime?
Exclude (like all TypeScript utility types) is evaluated entirely at COMPILE time. At runtime, types are erased and Exclude doesn’t exist, only the underlying JavaScript runs. This means you cannot use Exclude on runtime values like arrays or function arguments; it only constrains what types the compiler accepts.
