Что такое интерфейсы и типы в TypeScript, для чего они нужны и чем отличаются?
Что проверяют
Знаете ли вы реальные отличия, а не «интерфейсы для объектов, типы для остального». Отличий немного, и интервьюер ждёт именно их.
Как отвечать
Оба описывают форму данных и оба стираются при компиляции: в рантайме их нет.
interface User { id: number; name: string }
type UserAlias = { id: number; name: string };Практические различия:
- слияние объявлений: два
interfaceс одним именем объединяются,typeс одним именем это ошибка. На этом стоит расширение чужих типов из библиотек; - что можно описать:
typeумеет объединения (string | number), кортежи, условные и отображённые типы, шаблонные литералы. Интерфейс только форму объекта или функции; - расширение: у интерфейса
extends, у типа пересечение через&. Разница видна в конфликте полей:extendsдаст ошибку, пересечение молча создаст невозможный тип; - реализация классом:
implementsработает с обоими, если тип это объектная форма.
Практическое правило: публичный контракт объекта и всё, что может расширяться извне, описывают интерфейсом; объединения, кортежи и вычисляемые типы это type. Внутри одного проекта разница чаще стилистическая, важнее единообразие.
Где спотыкаются
Говорят, что интерфейсы быстрее компилируются. Разница есть только на очень больших объединениях и на практике не решает.
Не знают про слияние объявлений, а это единственное отличие, которое нельзя обойти.
Забывают, что оба не существуют в рантайме: проверить instanceof по интерфейсу нельзя, для проверок нужен предикат.