Skip to main content

What does Extract<T, U> do?

What does Extract<T, U> do?

Selects from T only the subtypes that are assignable to U. The implementation in lib.d.ts is equivalent to:

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

Examples:

javascript
type A = Extract<string | number | boolean, number | boolean>; // number | boolean type B = Extract<"a" | "b" | 1, string>; // "a" | "b" type C = Extract<{a:1} | {b:2}, {a:1} | {c:3}>; // {a:1} type D = Extract<"get" | "set" | "reset", `get${string}`>; // "get" type E = Extract<null | undefined | 0, null | undefined>; // null | undefined

How is Extract the opposite of Exclude?

Exclude<T, U> does the reverse: it removes from T everything that is assignable to U.

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

Relationships:

  • Extract<T, U> | Exclude<T, U> === T (a decomposition of the set)
  • Extract<T, U> & Exclude<T, U> === never (they do not overlap)
  • Identity: Extract<T, U> === Exclude<T, Exclude<T, U>>

A mini example:

javascript
type T = string | number | boolean; type OnlyStrings = Extract<T, string>; // string type NotStrings = Exclude<T, string>; // number | boolean

How does Extract work with union types?

It distributes over T: each member of the union in T is checked for assignability to U; the ones that pass are unioned together, the ones that do not are dropped.

javascript
type R1 = Extract<"a" | 1 | true, string | number>; // "a" | 1 type R2 = Extract<{x:1} | {y:2}, {x:1}>; // {x:1} type R3 = Extract<never, string>; // never

Subtleties:

  • With any:
    • Extract<T, any> -> always T.
    • Extract<any, U> -> any (because of special conditional-type rules with any).
  • With unknown:
    • Extract<T, unknown> -> T (everything is assignable to unknown).
    • Extract<unknown, U> -> never (except when unknown is explicitly assignable to U, which usually is not the case).
  • With never: always never.

Practical cases:

javascript
// Pull the string keys out of a mixed union type Keys = Extract<keyof any, string>; // string | number | symbol ∩ string = string // Filter a union by string format: type HttpGet = Extract<"GET" | "POST" | "PUT", "GET" | "HEAD">; // "GET" // Select only functions: type Fn = Extract<string | (() => void) | { run(): void }, Function>; // () => void

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.