Що робить Extract<T, U>?
Що робить Extract<T, U>?
Вибирає з T тільки ті підтипи, які сумісні (assignable) з U. Реалізація в lib.d.ts еквівалентна:
javascript
type Extract<T, U> = T extends U ? T : never;Приклади:
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Чим Extract протилежний до Exclude?
Exclude<T, U> робить зворотне: прибирає з T все, що сумісне з U.
javascript
type Exclude<T, U> = T extends U ? never : T;Співвідношення:
Extract<T, U> | Exclude<T, U> === T(декомпозиція множини)Extract<T, U> & Exclude<T, U> === never(вони не перетинаються)- Тотожність:
Extract<T, U> === Exclude<T, Exclude<T, U>>
Міні-приклад:
javascript
type T = string | number | boolean;
type OnlyStrings = Extract<T, string>; // string
type NotStrings = Exclude<T, string>; // number | booleanЯк Extract працює з union-типами?
Дистрибутивно по T: кожен член об'єднання з T перевіряється на сумісність з U; ті, що проходять, - об'єднуються, ті, що ні - відкидаються.
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Тонкощі:
- З
any:Extract<T, any>-> завждиT.Extract<any, U>->any(через особливі правила умовних типів зany).
- З
unknown:Extract<T, unknown>->T(все сумісне зunknown).Extract<unknown, U>->never(окрім випадків, колиunknownявно сумісний зU, що зазвичай не так).
- З
never: завждиnever.
Практичні кейси:
javascript
// Дістаємо ключі-рядки зі змішаного union
type Keys = Extract<keyof any, string>; // string | number | symbol ∩ string = string
// Фільтруємо union за форматом рядка:
type HttpGet = Extract<"GET" | "POST" | "PUT", "GET" | "HEAD">; // "GET"
// Вибираємо лише функції:
type Fn = Extract<string | (() => void) | { run(): void }, Function>; // () => voidКоротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.