TypeScript: type vs interface
В чём разница между type и interface?
type и interface во многом взаимозаменяемы, но имеют ключевые отличия.
// interface — описывает форму объекта или класса
interface User {
name: string;
age: number;
}
// type — описывает любой тип, не только объект
type ID = string | number;
type Callback = (value: string) => void;
type Point = { x: number; y: number };Расширение
// interface — через extends
interface Animal { name: string; }
interface Dog extends Animal { breed: string; }
// type — через пересечение (&)
type Animal = { name: string };
type Dog = Animal & { breed: string };Declaration Merging — только у interface
// interface можно дополнять в разных местах кода
interface Window { myProp: string; }
interface Window { anotherProp: number; }
// Итог: Window имеет оба свойства ✅
// type — нельзя объявить дважды с одним именем
type Window = { myProp: string; };
type Window = { anotherProp: number; }; // ❌ Error: Duplicate identifierDeclaration merging используется для расширения глобальных типов (например,
Window,ProcessEnv).
Уникальные возможности type
// Union — объединение типов
type Status = 'active' | 'inactive' | 'banned';
type ID = string | number;
// Tuple — массив с фиксированными типами позиций
type Pair = [string, number];
const p: Pair = ['hello', 42];
// Mapped types
type Readonly<T> = { readonly [K in keyof T]: T[K] };
type Optional<T> = { [K in keyof T]?: T[K] };
// Conditional types
type IsString<T> = T extends string ? true : false;Когда что использовать?
| Ситуация | Выбор |
|---|---|
| Форма объекта / API-контракт | interface |
| Публичные библиотеки (для merging) | interface |
| Классы и их контракты | interface |
| Union / Intersection типы | type |
Примитивные псевдонимы (type ID) | type |
| Tuple, Mapped types, Conditional types | type |
Практическое правило: используй
interfaceдля объектов и классов,type— для всего остального.