Skip to main content

Перетин типів

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& (перетин)
Використовується зinterfacetype і 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),
  • побудови потужних композиційних типів.

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

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

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