TYPESCRIPT

TypeScript Exclude Type: Syntax, Use Cases, and Examples

The Exclude utility type lets you remove specific types from a union, giving you more control over what’s allowed in variables, function parameters, and object keys. It's especially useful when working with union types, enums, or dynamic filtering logic in type definitions.

This guide walks through how Exclude works, how to use it with different TypeScript features, and how it compares to other type manipulation tools.


What Is Exclude?

Exclude<T, U> constructs a new type by removing from T any types that are assignable to U.

In plain terms, it subtracts one set of values from another.

How it works under the hood:

type Exclude<T, U> = T extends U ? never : T;

Each member of T is checked against U. If it matches, it gets replaced by never; otherwise, it stays.


Syntax

Exclude<UnionType, TypeToRemove>

Example

type Status = "active" | "inactive" | "pending";
type ActiveOnly = Exclude<Status, "inactive" | "pending">;
// Result: "active"

This allows you to define types that deliberately exclude certain values.


Why Use Exclude?

Exclude is helpful when you want to:

  • Remove unwanted values from a union
  • Narrow down enum options
  • Dynamically filter keys from object types
  • Create safer APIs or schema types
  • Refine generic utility types

It saves you from manually rewriting types and helps enforce constraints across your codebase.


Removing Values from Union Types

One of the most common uses of Exclude is to filter out specific values from a union.

Example

type Roles = "admin" | "editor" | "guest";
type PublicRoles = Exclude<Roles, "admin">;
// Result: "editor" | "guest"

This is especially useful when role-based access should limit certain values.


Using Exclude with Enums

You can also apply Exclude to enums or their string literal values.

Example

enum UserRole {
  Admin = "admin",
  Editor = "editor",
  Guest = "guest"
}

type DisplayableRoles = Exclude<UserRole, UserRole.Admin>;
// Result: "editor" | "guest"

You can also exclude by enum keys:

type Keys = keyof typeof UserRole;
// "Admin" | "Editor" | "Guest"

type NonAdminKeys = Exclude<Keys, "Admin">;

This pattern is useful for building UI options, permissions, or restricted logic.


Removing Keys from Object Types

Exclude works well with keyof and Pick to remove properties from objects.

Example

type User = {
  id: string;
  name: string;
  password: string;
};

type KeysToKeep = Exclude<keyof User, "password">;
type PublicUser = Pick<User, KeysToKeep>;

This builds a new object type without the password field—ideal for exposing safe data.

If you're just removing known keys, Omit<User, "password"> is easier. But using Exclude gives you flexibility when building dynamic or conditional types.


Conditional Filtering

Because Exclude is a conditional type, it plays nicely with other type-level logic.

Example

type Event = "click" | "hover" | "focus" | "scroll";
type AnimationEvents = Exclude<Event, "scroll">;

This helps when building UI components that don’t support certain events.


Excluding Multiple Values

You can remove more than one value at a time using a union in the second parameter.

type Color = "red" | "green" | "blue" | "yellow";

type Primary = Exclude<Color, "yellow">;
// "red" | "green" | "blue"

type WarmColors = Exclude<Color, "green" | "blue">;
// "red" | "yellow"

This pattern is helpful when modeling limited subsets of data types.


Filtering Object Properties with Mapped Types

You can pair Exclude with mapped types to rebuild objects minus certain keys.

Example

type Settings = {
  theme: string;
  layout: string;
  debug: boolean;
};

type Keys = keyof Settings; // "theme" | "layout" | "debug"
type WithoutDebug = Exclude<Keys, "debug">;

type UISettings = {
  [K in WithoutDebug]: Settings[K];
};
// Result: { theme: string; layout: string }

This gives you dynamic control over property selection.


Using Exclude in Generic Functions

Exclude can also power generic utility functions, where types are inferred and transformed.

Example

function filterOut<T, K extends T>(values: T[], toRemove: K[]): Exclude<T, K>[] {
  return values.filter((v) => !toRemove.includes(v as K)) as Exclude<T, K>[];
}

const all = ["a", "b", "c"] as const;
const result = filterOut(all, ["b"]);
// Inferred type: ("a" | "c")[]

This builds a filtered array and ensures the removed values are excluded at the type level.


Excluding Variants from Union of Objects

Exclude can filter out entire object shapes from union types.

type Action =
  | { type: "login"; user: string }
  | { type: "logout" }
  | { type: "refresh" };

type LoginOnly = Exclude<Action, { type: "logout" | "refresh" }>;
// Result: { type: "login"; user: string }

Useful in discriminated unions, especially when you want to isolate a single case.


How Exclude Behaves

Here are a few rules to keep in mind:

  • If the second type doesn’t overlap with the first, nothing is excluded.
  • If all members are excluded, the result is never.
  • It only works as expected with union types.

Example

type A = Exclude<string, number>; // string
type B = Exclude<"a" | "b", "a">; // "b"
type C = Exclude<"a", "a">;       // never

Custom Utilities with Exclude

You can build more advanced utilities by combining Exclude with conditional types.

Example: Omit keys by value type

type OmitByValue<T, V> = {
  [K in keyof T as T[K] extends V ? never : K]: T[K];
};

type Data = {
  id: number;
  name: string;
  metadata: object;
};

type CleanData = OmitByValue<Data, object>;
// Result: { id: number; name: string }

This removes keys from Data where the value type matches object.


Summary

The Exclude utility type helps you refine union types and object keys by removing unwanted members. It’s useful in countless situations—filtering enum values, reshaping API types, dynamically omitting fields, and building generic functions.

You can use Exclude on string literals, enum members, object keys, or entire union types. It plays well with other utility types like Pick, Omit, and Record, and is a key tool in your TypeScript type manipulation toolkit.

Learn TypeScript for Free
Start learning now
button icon
To advance beyond this tutorial and learn TypeScript by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

You can code, too.

© 2025 Mimo GmbH

Reach your coding goals faster