Type vs Interface
В TypeScript два способа описать форму объекта: type и interface. Оба работают, но есть различия.
Синтаксис
type User = {
name: string;
age: number;
};
interface User {
name: string;
age: number;
}
Результат одинаковый.
Что умеет только type
Union
type Status = 'idle' | 'loading' | 'success';
interface не умеет union.
Примитивы
type ID = string | number;
Кортежи
type Point = [number, number];
Условные типы
type IsString<T> = T extends string ? true : false;
Маппинг
type Partial<T> = { [K in keyof T]?: T[K] };
Что умеет только interface
Declaration merging
Несколько объявлений с одним именем объединяются:
interface User {
name: string;
}
interface User {
age: number;
}
// Итог: { name: string; age: number }
Полезно для расширения библиотечных типов.
Расширение через extends
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
Type тоже умеет через пересечение:
type Dog = Animal & { breed: string };
Что умеют оба
Расширение
// interface
interface Dog extends Animal {}
// type
type Dog = Animal & {};
Опциональные свойства
type User = { name?: string };
interface User { name?: string; }
readonly
type User = { readonly id: number };
interface User { readonly id: number; }
Индексы
type Dict = { [key: string]: number };
interface Dict { [key: string]: number; }
Разница в производительности
interface чуть быстрее при большом числе расширений. type создаёт новые типы при каждом использовании. На практике разница незаметна.
Ошибки в interface
interface не может выразить некоторые типы:
// Ошибка
interface Status = 'idle' | 'loading';
// Ок
type Status = 'idle' | 'loading';
Сообщения об ошибках
type иногда даёт более понятные ошибки в сложных случаях.
Рекомендации
Используй interface:
- Для публичных API библиотек
- Когда нужен declaration merging
- Для объектов и классов
Используй type:
- Для union, кортежей, примитивов
- Для условных и маппированных типов
- Когда не нужен merging
Согласованность: в проекте придерживайся одного подхода. Большинство современных проектов выбирают type из-за гибкости.
Пример: React-компонент
// type
type ButtonProps = {
variant: 'primary' | 'secondary';
onClick: () => void;
};
// interface
interface ButtonProps {
variant: 'primary' | 'secondary';
onClick: () => void;
}
В React чаще используют type.
Итоги
- Оба описывают форму объектов
typeумеет union, кортежи, условныеinterfaceумеет declaration merging- Оба умеют extends / пересечение
- Для проектов — один стиль
- Современный стандарт —
type