TYPESCRIPT

TypeScript Extract Type: Syntax, Use Cases, and Examples

The Extract utility type in TypeScript lets you filter a union to keep only the types that match a specific pattern. It's useful when you want to create more precise types by selecting only compatible members from a larger set.

This guide explores how Extract<T, U> works and shows how to use it with unions, object types, generics, and functions.


What Is Extract?

Extract<T, U> builds a new type by keeping only the members of T that are assignable to U.

How it works under the hood:

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

In a union, any part of T that matches U is retained; the rest becomes never.


Syntax

Extract<FromUnionType, MatchingType>

Example


type Input = "a" | "b" | "c";
type Output = Extract<Input, "a" | "c">;
// Result: "a" | "c"

This filters the original union to include only "a" and "c".


Why Use Extract?

Use Extract when you want to:

  • Filter a union to keep only specific values
  • Work with a subset of literal types or object shapes
  • Narrow types in reducers, UI events, or API schemas
  • Extract argument types or item types from generics
  • Create safer, more maintainable type definitions

It’s a powerful tool for building clean and expressive types without repeating yourself.


Filtering Literal Types

Extract is often used to narrow literal union types.

Example

type Roles = "admin" | "editor" | "viewer";

type AdminOnly = Extract<Roles, "admin">; // "admin"
type StaffRoles = Extract<Roles, "admin" | "editor">; // "admin" | "editor"

This is helpful when building role-based access types or validation logic.


Extracting Object Shapes from Unions

You can use Extract to pull out specific object types from a union of objects.

Example

type Action =
  | { type: "click"; payload: number }
  | { type: "hover"; payload: string }
  | { type: "scroll" };

type ClickAction = Extract<Action, { type: "click"; payload: number }>;
// Result: { type: "click"; payload: number }

This is useful in reducers, switch statements, or event systems where you need to handle only certain cases.


Extracting Function Argument Types

You can extract the argument types of a function using infer inside a conditional type.

Example

type GetArgs<T> = T extends (...args: infer A) => any ? A : never;

function log(message: string, level: number) {}
type LogArgs = GetArgs<typeof log>; // [message: string, level: number]

This pattern is handy when building wrappers, hooks, or test utilities.


Extracting Return Types

Although Extract isn’t specifically built for return types, you can still extract them using infer.

type GetReturn<T> = T extends (...args: any[]) => infer R ? R : never;

type Result = GetReturn<() => number>; // number

Use this in scenarios like API typing or function composition utilities.


Extracting Item Types from Arrays

To extract the item type from an array or tuple, use infer with a conditional type:

type ItemType<T> = T extends Array<infer U> ? U : never;

type Data = string[];
type Item = ItemType<Data>; // string

This is also useful for readonly arrays and tuples.


Working with Generic Types

Extract becomes even more powerful when used with generic unions.

Example

type Response<T> =
  | { status: "ok"; data: T }
  | { status: "error"; message: string };

type SuccessResponse = Extract<Response<string>, { status: "ok"; data: string }>;
// Result: { status: "ok"; data: string }

This is helpful in APIs or conditional rendering logic where success and error states need to be handled differently.


Filtering Complex Union Types

For larger discriminated unions, Extract can isolate only the types you care about.

type Shape =
  | { type: "circle"; radius: number }
  | { type: "square"; side: number }
  | { type: "triangle"; base: number; height: number };

type CirclesOnly = Extract<Shape, { type: "circle"; radius: number }>;
// Result: { type: "circle"; radius: number }

This helps keep logic focused and clean when working with switch statements or reducers.


Filtering Props in Generic Components

In generic components, Extract can isolate prop types that match a specific shape.

Example

type Props =
  | { kind: "button"; onClick: () => void }
  | { kind: "link"; href: string };

type ButtonProps = Extract<Props, { kind: "button" }>;
// Result: { kind: "button"; onClick: () => void }

This is common in React or Vue component libraries that use discriminated unions for prop variations.


Extracting Keys from Union of Objects

You can use Extract to isolate a particular type of object in a union based on a key.

type Events =
  | { type: "start"; value: string }
  | { type: "stop"; timestamp: number };

type StartEvent = Extract<Events, { type: "start" }>;
// Result: { type: "start"; value: string }

Combine this with keyof or infer if you want to dig deeper into the structure.


Role-Based Access Filtering

Extract is helpful in access control systems or feature flag logic.

type Permission = "read" | "write" | "delete" | "archive";

type WriteActions = Extract<Permission, "write" | "delete">;
// Result: "write" | "delete"

Use this for compile-time safety when assigning capabilities.


Using Extract in Reducers

When working with discriminated unions, Extract helps pull out the type for a specific action.

type Action =
  | { type: "create"; payload: string }
  | { type: "update"; payload: number }
  | { type: "delete"; id: number };

type UpdateAction = Extract<Action, { type: "update" }>;
// Result: { type: "update"; payload: number }

This is great for reducer type safety and autocomplete in IDEs.


Limitations

While Extract is flexible, it does have limits:

  • It works only on unions
  • It doesn’t match partial or fuzzy patterns—only exact matches
  • It runs at compile time, not runtime

If you need partial matching or fuzzy inference, you'll need custom types or helper functions.


Summary

Extract gives you a powerful way to filter types in TypeScript. You can narrow unions, isolate specific object shapes, pull out function parameters, or extract matching parts of generics.

Use it to simplify complex types, improve readability, and avoid unnecessary boilerplate. It’s especially useful in discriminated unions, role systems, reusable components, and any place where type safety and precision matter.

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