Kodokon kodokon.com

type против interface: extends и пересечение

Выбирай подходящую конструкцию, чтобы описывать и комбинировать объектные типы без дублирования кода.

8 мин · 3 вопросов

Открыть этот урок в Kodokon

Ты уже умеешь объявлять объектные типы. Настоящий вопрос в реальном проекте - выбрать между type и interface, а потом скомбинировать существующие типы, не дублируя код. Начнём с самого частого случая: описания сущностей, которые похожи друг на друга.

TYPESCRIPT
interface User {
  id: number;
  name: string;
}

interface Admin extends User {
  permissions: string[];
}

const admin: Admin = {
  id: 1,
  name: "Ada",
  permissions: ["users:write"],
};
Расширение интерфейса через extends

extends задаёт понятную связь: Admin - это User с дополнительными правами. С псевдонимом type ты получаешь тот же результат через оператор пересечения &, который объединяет несколько форм в одну. Это идеальный инструмент для сквозных свойств, например для меток времени, которые есть у всех твоих сущностей.

TYPESCRIPT
type Timestamps = {
  createdAt: Date;
  updatedAt: Date;
};

type Product = {
  id: number;
  label: string;
};

type StoredProduct = Product & Timestamps;
Комбинирование типов через пересечение &

Так что же выбрать? По-настоящему важны два отличия. Во-первых, только type может дать имя объединению вроде 'active' | 'archived'. Во-вторых, два объявления interface с одним и тем же именем сливаются автоматически: удобно, когда ты дополняешь типы библиотеки, и опасно, когда это происходит случайно.

TYPESCRIPT
type Status = "active" | "archived";

interface Config {
  locale: string;
}

interface Config {
  debug: boolean;
}

const config: Config = { locale: "fr", debug: true };
Объединения доступны только через type, а объявления interface сливаются

Проверка знаний

Убедись, что запомнил ключевые моменты этого урока.

  1. Тебе нужно дать имя типу 'draft' | 'published'. Какая конструкция обязательна?
    • interface
    • type
    • Подходят обе
    • enum
  2. Два объявления interface Config { ... } находятся в одной области видимости. Что произойдёт?
    • Сразу возникнет ошибка компиляции
    • Второе перезапишет первое
    • Они сольются в один интерфейс
    • Приоритет будет у первого
  3. Какой оператор объединяет два псевдонима объектных типов в один тип, требующий свойства обоих?
    • |
    • &
    • extends