Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Перетин типів». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Перетин типів (`&`)** - це спосіб об'єднати кілька типів в один так, щоб отриманий тип містив усі властивості та методи всіх об'єднаних типів. **Ключове:** `A | B` означає "або A, або B", тоді як `A & B` означає "і A, і B" одночасно.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Що таке перетин типів (Intersection Types) > **Перетин типів (**`&`**)** - це спосіб **об'єднати кілька типів в один**, > щоб отриманий тип містив **усі властивості та методи всіх об'єднаних типів**. Простіше кажучи: > Intersection = **тип, який відповідає всім об'єднаним типам одразу.** --- ### Синтаксис ```javascript type Combined = TypeA & TypeB; ``` > Тепер змінна типу `Combined` має відповідати і `TypeA`, і `TypeB`. --- ### Приклад ```javascript type Person = { name: string }; type Contact = { email: string }; type User = Person & Contact; const u: User = { name: "Tim", email: "tim@example.com", }; ``` Об'єкт `u` повинен містити **і** `name`**, і** `email`, тому що тип `User` об'єднує обидва. --- ## 2. Перетини з інтерфейсами Працює однаково з `interface` і `type`: ```javascript interface Position { x: number; y: number; } interface Shape { color: string; } type ColoredPoint = Position & Shape; const point: ColoredPoint = { x: 10, y: 20, color: "red", }; ``` --- ## 3. Перетини можна робити між різними структурами ```javascript type Identifiable = { id: number }; type Timestamped = { createdAt: Date }; type Entity = Identifiable & Timestamped; const post: Entity = { id: 1, createdAt: new Date(), }; ``` > Тепер `Entity` вимагає і `id`, і `createdAt`. --- ## 4. Перетин несумісних типів Якщо в типів, що перетинаються, є **однакові поля з різними типами**, TypeScript вважатиме їх **несумісними** (результатом буде `never`). ```javascript type A = { value: string }; type B = { value: number }; type C = A & B; // value має бути і string, і number -> неможливо const c: C = { value: "123" }; // Помилка ``` > `C["value"]` тут матиме тип `never`, > тобто "неможливе значення". --- ## 5. Перетини та union-типи (можна комбінувати) Можна будувати складні типи, поєднуючи `|` і `&`. ```javascript type Admin = { role: "admin"; permissions: string[] }; type User = { role: "user"; name: string }; type Person = (Admin | User) & { id: number }; ``` Тепер: - `Person` може бути або `Admin`, або `User`; - але **завжди** повинен мати `id`. ```javascript const p1: Person = { id: 1, role: "admin", permissions: ["delete"] }; const p2: Person = { id: 2, role: "user", name: "Tim" }; ``` Все коректно. --- ## 6. Перетини та класи Перетин можна використовувати, щоб **об'єднати кілька інтерфейсів** без успадкування: ```javascript interface Flyable { fly(): void; } interface Swimmable { swim(): void; } type Duck = Flyable & Swimmable; const duck: Duck = { fly: () => console.log("Flies"), swim: () => console.log("Swims"), }; ``` > Те саме можна було б зробити через `interface Duck extends Flyable, Swimmable`, > але `&` працює і для `type`, і для `interface`, і для примітивів. --- ## 7. Перетини з примітивами Так, перетини можливі і для простих типів, але рідко корисні: ```javascript type T = string & number; // never (неможливий тип) ``` > Тому що значення не може бути одночасно і рядком, і числом. > > У цьому разі перетин дає `never`. --- ## 8. Перетини та узагальнені типи (Generics) ```javascript function merge<T, U>(a: T, b: U): T & U { return { ...a, ...b }; } const result = merge({ name: "Tim" }, { age: 25 }); // result має тип { name: string; age: number } ``` > Дуже частий прийом - "склеїти" об'єкти в один > з типом, що містить об'єднані властивості. --- ## 9. Перетини проти успадкування інтерфейсів | Особливість | `extends` | `&` (перетин) | |---|---|---| | Використовується з | `interface` | `type` і `interface` | | Об'єднує структури | Так | Так | | Дозволяє комбінувати `type` + `interface` | Ні | Так | | Механізм | декларативний (успадкування) | структурний (композиція) | > Простіше кажучи: > > - `extends` - це "успадкуй від батька", > - `&` - це "з'єднай обидва". --- ## 10. Де реально використовується `&` - об'єднання даних з метаданими ```javascript type WithId<T> = T & { id: string }; ``` - об'єднання інтерфейсів API та DTO ```javascript type Request = AuthHeaders & BodyPayload; ``` - об'єднання типів з опціями ```javascript type Config = BaseConfig & { debug?: boolean }; ``` - об'єднання класових контрактів ```javascript type Controller = HasLogger & HasRoutes; ``` --- ## Підсумок > **Перетин типів (**`&`**)** - це механізм об'єднання кількох типів в один, > який **містить усі властивості** всіх об'єднаних структур. > > Використовується, коли об'єкт повинен **відповідати одразу кільком типам**. > > Формула проста: > > - `A | B` -> **або A, або B** > - `A & B` -> **і A, і B** > > Перетини ідеально підходять для: > > - розширення структур даних, > - об'єднання типів з різних модулів, > - комбінування generic-типів (`T & U`), > - побудови потужних композиційних типів.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.