> Почему проверка типа через 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 используют:

  1. Type guards - пользовательские функции с возвращаемым типом obj is Interface
  2. Discriminated unions - добавление литерального поля-дискриминатора
  3. Библиотеки валидации - zod, io-ts, class-validator
  4. Проверка наличия свойств - 'property' in obj

Для классов instanceof работает, так как классы существуют в runtime и имеют prototype chain.

Пример кода

TYPESCRIPT
interface 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 union
interface 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

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью