Перейти к содержимому

Union & Intersection

Базовая алгебра типов. Частая путаница: A | B «может быть либо A, либо B» — то есть пересечение возможностей. А A & B требует одновременно все поля. На интервью просят объяснить, что такое юнион функций и почему у него можно вызвать только общие методы (intersection of capabilities).

Union — значение может быть одним из, поэтому доступны только общие операции.

type Id = string | number;
function len(id: Id) {
// id.length; // ошибка: number нет .length
if (typeof id === 'string') return id.length;
return String(id).length;
}
// Юнион функций: можно вызывать только с пересечением аргументов
type Cb = ((s: string) => void) | ((n: number) => void);
declare const cb: Cb;
// cb('x'); // Error: each member of Cb expects different arg

Intersection — значение должно удовлетворять всем составляющим одновременно.

type WithId = { id: string };
type WithName = { name: string };
type User = WithId & WithName; // обязаны быть оба поля
const u: User = { id: 'u_1', name: 'Ada' };
// Конфликт типов даёт never у поля
type Bad = { x: number } & { x: string }; // x: number & string = never

Интуиция: union расширяет множество значений, intersection сужает. У объектных типов поведение «выглядит наоборот» из-за того, что объект — это набор требований.

Итог: | — общее поведение значения; & — общее поведение требований к объекту.