Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить Exclude<T, U>?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`Exclude<T, U>`** - утилітарний тип, що створює новий union, виключаючи з `T` усі елементи, сумісні з `U`; реалізований як `T extends U ? never : T`. **Ключове:** якщо `U` не перетинається з `T`, результат лишається без змін, а на відміну від `Omit`, `Exclude` працює з елементами union, а не з ключами об'єкта.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Що робить `Exclude<T, U>` > `Exclude<T, U>` - створює **новий тип**, > виключаючи з `T` усі типи, які **сумісні з** `U`. Простіше кажучи - він *"віднімає"* з одного об'єднання (`union`) інше. --- ### Приклад ```javascript type Letters = 'a' | 'b' | 'c'; type WithoutB = Exclude<Letters, 'b'>; // => 'a' | 'c' ``` > Тип `'b'` виключено, а `'a'` і `'c'` залишилися. --- ## 2. Як `Exclude` працює з union-типами Коли `T` - це об'єднання (`union`), TypeScript **проходить по кожному елементу** `T` і **видаляє** ті, що сумісні з типом `U`. --- ### Приклад 1 ```javascript type T = 'a' | 'b' | 'c'; type U = 'a' | 'c'; type Result = Exclude<T, U>; // 'b' ``` > `'a'` і `'c'` були в `U`, отже виключені. > Залишився `'b'`. --- ### Приклад 2 ```javascript type Primitive = string | number | boolean; type NoStrings = Exclude<Primitive, string>; // number | boolean ``` > `string` виключено, решта типів збереглися. --- ## 3. Що станеться, якщо `U` не входить у `T` Якщо `U` не перетинається з `T`, то **нічого не видаляється**, і результатом буде просто `T`. --- ### Приклад ```javascript type T = 'a' | 'b'; type U = 'x' | 'y'; type Result = Exclude<T, U>; // 'a' | 'b' (без змін) ``` > TypeScript "намагається відняти", але не знаходить збігів - > тому `Exclude` нічого не змінює. --- ## 4. Як `Exclude` реалізований усередині Ось як виглядає його реальна реалізація в TypeScript: ```javascript type Exclude<T, U> = T extends U ? never : T; ``` Пояснення: - Перевіряється кожен елемент `T` окремо: якщо він сумісний з `U`, замінюється на `never` (виключається); - решта зберігаються. --- ## 5. Приклад з `never` ```javascript 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` | --- ### Приклад різниці на практиці ```javascript // 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-поля інтерфейсу ```javascript interface ApiResponse { status: 'success' | 'error' | 'loading'; data: string; } type NoLoading = Exclude<ApiResponse['status'], 'loading'>; // 'success' | 'error' ``` --- ### Приклад: створення типу "без null і undefined" ```javascript 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` - з *ключами об'єкта* |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.