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 | undefinedHow 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 | booleanHow 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>; // neverSubtleties:
- With
any:Extract<T, any>-> alwaysT.Extract<any, U>->any(because of special conditional-type rules withany).
- With
unknown:Extract<T, unknown>->T(everything is assignable tounknown).Extract<unknown, U>->never(except whenunknownis explicitly assignable toU, which usually is not the case).
- With
never: alwaysnever.
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>; // () => voidShort Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.