Що робить Exclude<T, U>?
1. Що робить Exclude<T, U>
Exclude<T, U>- створює новий тип, виключаючи зTусі типи, які сумісні зU.
Простіше кажучи - він "віднімає" з одного об'єднання (union) інше.
Приклад
type Letters = 'a' | 'b' | 'c';
type WithoutB = Exclude<Letters, 'b'>;
// => 'a' | 'c'Тип
'b'виключено, а'a'і'c'залишилися.
2. Як Exclude працює з union-типами
Коли T - це об'єднання (union),
TypeScript проходить по кожному елементу T
і видаляє ті, що сумісні з типом U.
Приклад 1
type T = 'a' | 'b' | 'c';
type U = 'a' | 'c';
type Result = Exclude<T, U>;
// 'b'
'a'і'c'були вU, отже виключені. Залишився'b'.
Приклад 2
type Primitive = string | number | boolean;
type NoStrings = Exclude<Primitive, string>;
// number | boolean
stringвиключено, решта типів збереглися.
3. Що станеться, якщо U не входить у T
Якщо U не перетинається з T,
то нічого не видаляється, і результатом буде просто T.
Приклад
type T = 'a' | 'b';
type U = 'x' | 'y';
type Result = Exclude<T, U>;
// 'a' | 'b' (без змін)TypeScript "намагається відняти", але не знаходить збігів - тому
Excludeнічого не змінює.
4. Як Exclude реалізований усередині
Ось як виглядає його реальна реалізація в TypeScript:
type Exclude<T, U> = T extends U ? never : T;Пояснення:
- Перевіряється кожен елемент
Tокремо: якщо він сумісний зU, замінюється наnever(виключається); - решта зберігаються.
5. Приклад з never
type T = 'a' | 'b';
type U = 'a';
type Result = Exclude<T, U>; // 'b'
// по суті це працює як:
type Result =
('a' extends 'a' ? never : 'a') |
('b' extends 'a' ? never : 'b');
// => never | 'b' → 'b'6. Різниця між Exclude і Omit
Ці типи схожі за змістом ("видалити щось"), але працюють у різних контекстах.
| Порівняння | Exclude<T, U> | Omit<T, K> |
|---|---|---|
| Працює з | union-типами | об'єктами (інтерфейсами) |
| Видаляє | типи (значення з об'єднання) | властивості (ключі) |
| Приклад входу | `'a' | 'b' |
| Приклад видалення | `Exclude<'a' | 'b' |
| Основа | умовні типи (extends) | комбінація Pick + Exclude |
Приклад різниці на практиці
// Exclude
type Letters = 'a' | 'b' | 'c';
type Result1 = Exclude<Letters, 'b'>;
// 'a' | 'c'
// Omit
interface User {
id: number;
name: string;
email: string;
}
type Result2 = Omit<User, 'email'>;
// { id: number; name: string }
Excludeпрацює на рівні типів значень,Omit- на рівні ключів об'єкта.
7. Комбінування з іншими утилітами
Приклад: виключити частину union-поля інтерфейсу
interface ApiResponse {
status: 'success' | 'error' | 'loading';
data: string;
}
type NoLoading = Exclude<ApiResponse['status'], 'loading'>;
// 'success' | 'error'Приклад: створення типу "без null і undefined"
type Clean<T> = Exclude<T, null | undefined>;
type Value = Clean<string | null | undefined>;
// stringПідсумок
| Питання | Відповідь |
|---|---|
Що робить Exclude<T, U> | Видаляє з T усі типи, сумісні з U |
| Як працює з union-типами | Перевіряє кожен елемент і виключає ті, що збігаються |
Що, якщо U не входить у T | Результат лишається тим самим (T не змінюється) |
Чим відрізняється від Omit | Exclude працює з union, а Omit - з ключами об'єкта |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.