Intersection типы
Intersection (&) — тип, который объединяет несколько типов. Объект должен удовлетворять всем.
Базовый пример
type Person = { name: string };
type Employee = { company: string };
type Worker = Person & Employee;
const worker: Worker = {
name: 'Алиса',
company: 'Acme',
};
Несколько типов
type A = { a: string };
type B = { b: number };
type C = { c: boolean };
type ABC = A & B & C;
Добавление к существующему
type User = {
id: number;
name: string;
};
type UserWithEmail = User & {
email: string;
};
В отличие от union
- Union — «или»
- Intersection — «и»
// A или B
type U = A | B;
// A и B
type I = A & B;
Конфликты
Если поля одного типа противоречат другому — результат never:
type A = { value: string };
type B = { value: number };
type C = A & B;
// { value: never }
Создать объект такого типа нельзя.
Пересечение с примитивами
type T = string & number; // never
Практическое применение
Миксины
type Timestamped = {
createdAt: Date;
updatedAt: Date;
};
type SoftDeletable = {
deletedAt: Date | null;
};
type Post = {
title: string;
} & Timestamped & SoftDeletable;
Расширение сторонних типов
import type { Request } from 'express';
type AuthRequest = Request & {
user: { id: number };
};
Пересечение с классами
class Base {
id = 1;
}
type Extended = Base & { name: string };
Когда использовать
- Композиция из независимых частей
- Расширение внешних типов
- Миксины
- Когда
interface extendsне подходит (например, расширение union)
Union vs Intersection
type A = { a: string };
type B = { b: number };
type U = A | B;
// { a: string } или { b: number }
const u1: U = { a: 'x' }; // ок
const u2: U = { b: 1 }; // ок
const u3: U = { a: 'x', b: 1 }; // ок
type I = A & B;
// { a: string; b: number }
const i1: I = { a: 'x' }; // ошибка
const i2: I = { a: 'x', b: 1 }; // ок
Итоги
&— объединение типов- Объект удовлетворяет всем
- Конфликты дают
never - Для миксинов и расширения
- Отличать от union: «и» против «или»