Skip to main content

Об'єднання типів

Що таке об'єднання типів (Union Type)

Об'єднання типів - це тип, який може бути одним із кількох указаних варіантів.

У TypeScript об'єднання створюються через вертикальну риску |:

javascript
let value: string | number;

Це означає:

value може бути або рядком, або числом, але нічим іншим.


Приклад 1. Найпростіше об'єднання

javascript
let id: string | number; id = 42; // OK id = "42"; // OK id = true; // Помилка

Так ти обмежуєш набір допустимих типів, але при цьому зберігаєш гнучкість.


Приклад 2. Об'єднання в параметрах функції

javascript
function printId(id: string | number) { console.log("ID:", id); } printId(123); // OK printId("abc"); // OK

Функція приймає або рядок, або число, але нічого іншого.


Приклад 3. Не всі методи доступні при union

Коли TypeScript не може точно визначити тип під час виконання, він дозволяє лише спільні методи для всіх типів.

javascript
function printId(id: string | number) { console.log(id.length); // Помилка - у number немає .length }

Рішення: звузити тип (type narrowing):

javascript
function printId(id: string | number) { if (typeof id === "string") { console.log("Довжина рядка:", id.length); } else { console.log("Число:", id.toFixed(2)); } }

Після перевірки typeof TypeScript "розуміє", який конкретно тип використовується.


Приклад 4. Union усередині об'єктів

Можна об'єднувати різні форми об'єктів:

javascript
type User = { name: string; age: number }; type Admin = { name: string; permissions: string[] }; type Person = User | Admin; const user1: Person = { name: "Tim", age: 25 }; // OK const user2: Person = { name: "Alex", permissions: [] }; // OK const user3: Person = { name: "Bob" }; // Помилка: age або permissions обов'язкові

Приклад 5. Використання в switch (discriminated unions)

TypeScript особливо добре працює з об'єднаннями, якщо додати дискримінатор - спільне поле для розрізнення варіантів.

javascript
type Shape = | { kind: "circle"; radius: number } | { kind: "square"; side: number }; function area(shape: Shape): number { switch (shape.kind) { case "circle": return Math.PI * shape.radius ** 2; case "square": return shape.side ** 2; } } area({ kind: "circle", radius: 10 }); // OK

Це називається дискриміноване об'єднання (discriminated union) - один із найпотужніших патернів у TS.


Приклад 6. Об'єднання літеральних типів

Можна створювати обмежені набори значень:

javascript
type Direction = "up" | "down" | "left" | "right"; let move: Direction; move = "up"; // OK move = "down"; // OK move = "forward"; // Помилка

Дуже зручно для статусів, ролей, режимів тощо.


Приклад 7. Об'єднання з null і undefined

Типові приклади - змінні, які можуть бути невизначені:

javascript
let username: string | null = null; function printName(name: string | undefined) { if (name) { console.log(name.toUpperCase()); } }

Такі об'єднання допомагають TypeScript захищати код від помилок "Cannot read property of null".


Приклад 8. Об'єднання з type alias та інтерфейсами

javascript
type Status = "loading" | "success" | "error"; type Response = { status: Status; data?: string }; function handleResponse(res: Response) { if (res.status === "success") { console.log(res.data); } }

Union vs Intersection (| vs &)

ОператорНазваПрикладЗначення
|Union (об'єднання)A | Bоб'єкт, який є або A, або B
&Intersection (перетин)A & Bоб'єкт, який є і A, і B одночасно

Приклад відмінності:

javascript
type Dog = { bark: () => void }; type Cat = { meow: () => void }; type PetUnion = Dog | Cat; // або пес, або кіт type PetBoth = Dog & Cat; // і те, і те (істота, що вміє гавкати і нявкати)

Підсумок

КонцепціяПриклад
Простий unionstring | number
Об'єднання об'єктів{a: number} | {b: string}
Літеральні об'єднання"on" | "off"
Дискримінований union{ kind: "circle" } | { kind: "square" }
Union з null/undefinedstring | null

Просте визначення:

Union (|) - це "АБО" для типів.

Змінна може бути одним із кількох типів, і TypeScript вимагає, щоб ти явно вказав, який саме використовується під час роботи.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.