🤔 В чём отличие interface и type в TypeScript на самом деле?
Этот вопрос часто задают на собеседованиях — и, что удивительно, большинство кандидатов и даже интервьюеров не знают главного различия.
──
✨ Базовые отличия:
1️⃣ interface с одинаковым именем склеивается (merge), но только в рамках одного контекста (scope). type, наоборот, выдаст ошибку при попытке повторного объявления.
2️⃣ interface может наследовать другие интерфейсы, но и типы тоже может наследовать — только если эти типы имеют объектную форму и не содержат объединений (union), а type объединяет и типы, и интерфейсы через пересечение (&).
3️⃣ interface описывает только объекты и функции, а type может описывать любой тип, включая примитивы, объединения (|) и пересечения (&).
──
⚙️ Менее очевидные различия:
4️⃣ interface можно использовать с implements (в классах), он также может описывать new(). type в implements работает ограниченно — описывать new() нельзя.
5️⃣ type поддерживает объединения (union), а interface — нет.
type Entity = | { type: 'user'; name: string } | { type: 'post'; title: string };
──
🔥 Самое важное различие:
6️⃣ interface — это статическая структура, а type — динамическая.
В interface нельзя описать вычисляемые ключи, он требует фиксированную структуру.
А type позволяет создавать динамические типы:
type User = { id: number; name: string }; type ReadonlyUser = { [K in keyof User]: User[K] };
✅ Это называется mapped type, и оно возможно только с type.
Если попытаться сделать то же самое через интерфейс:
interface ReadonlyUser { [K in keyof User]: User[K]; // ❌ Ошибка }
TypeScript сообщит: "A mapped type may not declare properties or methods".
👇 А это разве не динамический interface? interface Dictionary { [key: string]: number; }
Нет, это не настоящая динамика, а просто маска для любых свойств — без вычислений и зависимостей от других типов.
Это называется index signature (индексная подпись) — способ сказать, что объект может содержать свойства с любыми строковыми именами определённого типа.
──
⚡️ Производительность:
7️⃣ Из-за вычислений type может компилироваться медленнее, поскольку компилятору нужно разрешать больше зависимостей между типами.
──
✅ Итог:
▪️ interface — для описания структур и контрактов классов. ▪️ type — для гибких, вычисляемых и комбинированных типов.
──
👉 Сохраняй, чтобы не забыть и удивить любого интервьювера на собеседовании. 😁