Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чим перетин типів (&) відрізняється від extends в інтерфейсах?

Обидва способи складають тип з кількох частин:

interface HasId { id: number }
interface HasTimestamps { createdAt: string; updatedAt: string }

// успадкування інтерфейсів
interface Post extends HasId, HasTimestamps {
  title: string;
}

// перетин типів
type Comment = HasId & HasTimestamps & { body: string };

Для простих випадків результат однаковий. Різниця - у конфліктах і в тому, як компілятор з ними працює.

1. Конфлікт властивостей.

interface A { status: string }
interface B extends A { status: number }   // помилка одразу: number не сумісний з string

type C = { status: string } & { status: number };   // помилки немає...
// ...але C['status'] - це never: жодне значення не підійде, і об'єкт типу C не створити

extends повідомляє про несумісність в оголошенні. Перетин мовчки дає never, і помилка з'являється далеко - там, де намагаються створити об'єкт.

2. Продуктивність перевірки типів. Інтерфейси кешуються як іменовані типи; компілятор порівнює їх за назвою. Великі перетини перераховуються щоразу. Документація TypeScript з продуктивності радить у великих кодових базах складати об'єктні типи через interface ... extends, а не через довгі ланцюжки &.

3. Що можна скласти. extends в інтерфейсі - лише з об'єктними типами (й класами). Перетин працює з будь-якими типами, включно з об'єднаннями й узагальненнями:

type WithMeta<T> = T & { meta: { requestId: string } };
type Branded = string & { readonly __brand: 'UserId' };

Перетин з об'єднаннями розподіляється: (A | B) & C - це (A & C) | (B & C).

Перетин примітивів - string & number - дає never: значення, що водночас рядок і число, не існує.

Практичні правила:

  • об'єктні сутності й їх розширення - interface ... extends: краща діагностика й швидкість;
  • узагальнені «домішки» (T & { ... }), брендовані типи, композиція типів з утиліт - перетин;
  • якщо перетин дає несподіваний never, - майже завжди конфлікт однойменних властивостей.

Докладніше в документації: Перетин типів

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання