> Почему проверка типа через instanceof не работает с интерфейсами в TypeScript (TypeScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Точка
Стек: TypeScript
> Пример ответа
Короткий ответ
instanceof проверяет наличие конструктора в prototype chain объекта на этапе runtime. Интерфейсы TypeScript - это чисто compile-time конструкция, которая полностью стирается при транспиляции в JavaScript. В runtime от интерфейса не остаётся никакого кода, поэтому instanceof физически не может проверить соответствие интерфейсу - ему просто не на что ссылаться.
Подробное объяснение
TypeScript - это надстройка над JavaScript, которая добавляет статическую типизацию только на этапе разработки и компиляции. Интерфейсы существуют исключительно в мире типов TypeScript и не порождают никакого runtime-кода. Когда вы пишете instanceof SomeInterface, TypeScript выдаст ошибку компиляции, потому что интерфейс не является конструктором.
instanceof работает с классами и функциями-конструкторами, у которых есть свойство prototype. В runtime JavaScript проверяет, присутствует ли Constructor.prototype в цепочке прототипов объекта. Интерфейсы не имеют prototype - это абстрактное описание структуры объекта.
TypeScript использует структурную типизацию (duck typing): объект соответствует интерфейсу, если у него есть все необходимые свойства с правильными типами. Это принципиально отличается от номинальной проверки instanceof, которая требует явной связи через наследование.
На практике
Для проверки соответствия интерфейсу в runtime используют:
- Type guards - пользовательские функции с возвращаемым типом
obj is Interface - Discriminated unions - добавление литерального поля-дискриминатора
- Библиотеки валидации - zod, io-ts, class-validator
- Проверка наличия свойств -
'property' in obj
Для классов instanceof работает, так как классы существуют в runtime и имеют prototype chain.
Пример кода
TYPESCRIPTinterface User {name: string;age: number;}class Admin {constructor(public name: string, public age: number) {}}// ❌ Ошибка: 'User' only refers to a type, but is being used as a value here// console.log(user instanceof User);// ✅ Работает с классамиconst admin = new Admin('Alice', 30);console.log(admin instanceof Admin); // true// ✅ Type guard для интерфейсаfunction isUser(obj: any): obj is User {return typeof obj === 'object' &&obj !== null &&typeof obj.name === 'string' &&typeof obj.age === 'number';}// ✅ Discriminated unioninterface SuccessResponse {kind: 'success';data: string;}interface ErrorResponse {kind: 'error';message: string;}type Response = SuccessResponse | ErrorResponse;function handleResponse(res: Response) {if (res.kind === 'success') {console.log(res.data); // TypeScript знает, что это SuccessResponse}}
Как отвечать на собеседовании
Начни с ключевой причины - интерфейсы стираются в runtime. Затем объясни разницу между compile-time и runtime проверками. Упомяни структурную vs номинальную типизацию. Покажи, что понимаешь альтернативы: type guards, discriminated unions. Для senior-уровня добавь про рефлексию и декораторы в TypeScript, если интервьюер спросит про более сложные сценарии.
Что проверяет интервьюер
- Понимание разницы между системой типов TypeScript и runtime JavaScript
- Знание механизма работы
instanceofв JS - Осознание, что интерфейсы - это compile-time конструкция
- Умение предложить практические альтернативы для runtime проверок
- Понимание структурной типизации
Типичные ошибки
- Утверждение, что
instanceofвообще не работает в TypeScript - работает, но только с классами - Попытка использовать
instanceofс type alias - та же проблема, типы стираются - Путаница между интерфейсами и абстрактными классами - последние существуют в runtime
- Предложение использовать
typeofдля проверки интерфейсов - typeof проверяет только примитивные типы - Игнорирование discriminated unions как более идиоматичного подхода в TypeScript
> Похожие задачи по frontend
Как реализовать динамически настраиваемое поле в интерфейсе TypeScript
Какие сущности TypeScript остаются в рантайме после транспиляции
Что может быть неправильно в решении функции для вычисления площади фигур с использованием типов и интерфейсов TypeScript
Что такое типы any и unknown в TypeScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью