TypeScript: Type vs Interface — разница, правила выбора и сравнение на примерах
Разбор фундаментального вопроса TypeScript: когда использовать type, а когда interface. Слияние деклараций, union-типы, примитивы, кортежи и расширение.
Модули 11–12: TypeScript от основ до дженериков
Изучите строгую типизацию, дженерики и утилиты TypeScript на интерактивных задачах.
В TypeScript как type (псевдоним типа, Type Alias), так и interface (интерфейс) используются для описания формы данных и контрактов объектов. В базовых примерах они выглядят почти одинаково:
// Объявление через interface
interface UserInterface {
name: string;
age: number;
}
// Объявление через type
type UserType = {
name: string;
age: number;
};
Однако под капотом между ними есть принципиальные архитектурные различия, знание которых отличает Senior-инженера от новичка.
1. Слияние деклараций (Declaration Merging)
Интерфейсы в TypeScript умеют автоматически объединяться, если объявлены с одинаковым именем несколько раз в одной области видимости. Типы (type) повторно объявлять строго запрещено:
// ✅ ИНТЕРФЕЙСЫ ОБЪЕДИНЯЮТСЯ:
interface Window {
myAnalyticsToken: string;
}
interface Window {
appTheme: 'light' | 'dark';
}
// Итоговый глобальный Window содержит оба поля без конфликтов!
// ❌ ТИПЫ ВЫЗЫВАЮТ ОШИБКУ:
type Config = { port: number };
type Config = { host: string }; // Error: Duplicate identifier 'Config'
Секрет успеха:
Declaration Merging незаменим при создании npm-библиотек или расширении встроенных типов браузера и Node.js. Разработчик может дописать новые свойства в ваш интерфейс, не вмешиваясь в исходный код пакета.
2. Примитивы, объединения (Union) и кортежи
type обладает гораздо более широким выразительным спектром, чем interface. Он может описывать любые типы данных:
// 1. Объединения (Union Types) — только через type!
type Status = 'pending' | 'success' | 'error';
type ID = string | number;
// 2. Кортежи (Tuples) — строго фиксированная структура:
type GeoCoordinate = [latitude: number, longitude: number];
// 3. Извлечение типов (Type Queries & Mapped Types):
type KeysOfUser = keyof UserInterface;
type ReadonlyUser = { readonly [K in keyof UserInterface]: UserInterface[K] };
Обратите внимание:
interfaceумеет описывать только форму объектов и сигнатуры функций. Вы не можете создатьinterface ID = string | number— компилятор выдаст синтаксическую ошибку.
3. Синтаксис расширения (extends vs &)
Расширение интерфейсов через extends:
interface Animal {
name: string;
}
interface Dog extends Animal {
bark(): void;
}
Расширение типов через пересечение (&):
type Animal = {
name: string;
};
type Dog = Animal & {
bark(): void;
};
Совет эксперта по производительности:
Компилятор TypeScript проверяетinterface extendsбыстрее, чем пересечениеtype &. Интерфейсы кэшируют плоские карты свойств, в то время как операция пересечения требует рекурсивного слияния всех вложенных структур.
4. Сводная таблица сравнения
| Критерий | interface | type |
|---|---|---|
| Описание формы объектов | ✅ Да | ✅ Да |
| Описание функций и методов | ✅ Да | ✅ Да |
| Объединения (Union: `A | B`) | ❌ Нет |
Примитивные псевдонимы (type ID = string) | ❌ Нет | ✅ Да |
Кортежи (Tuples: [number, string]) | ❌ Нет | ✅ Да |
| Слияние деклараций (Merging) | ✅ Да | ❌ Ошибка |
| Синтаксис наследования | extends | & (intersection) |
| Производительность компилятора | ⚡ Максимальная | Высокая |
5. Практическое правило: Что выбирать в 2026 году?
Современный инженерный стандарт индустрии:
Ключевое правило выбора:
- Используйте
interfaceпо умолчанию для всех бизнес-сущностей, DTO, компонентов и публичных API.- Используйте
typeдля Union-типов, состояний, кортежей, утилитных преобразований (Omit,Pick) и примитивов.
Понравилась шпаргалка?
В платформе CopyPastWorld собрано более 400 интерактивных уроков с практическими заданиями, автотестами и поддержкой сообщества.
