> Как определить тип переменной через ReturnType в TypeScript (TypeScript)

Уровень: middle · Роль: frontend · Категория: Технические вопросы

Компании: IT-One

Стек: TypeScript

> Пример ответа

Короткий ответ

ReturnType<T> - встроенный условный тип в TypeScript, который извлекает тип возвращаемого значения из сигнатуры функции. Используется как ReturnType<typeof myFunction>, где typeof получает тип функции. Работает с обычными функциями, async-функциями и generic-функциями, но не с перегруженными. Позволяет динамически получать тип результата вызова функции без её фактического выполнения.

Подробное объяснение

ReturnType реализован как условный тип с infer:

TYPESCRIPT
type ReturnType<T extends (...args: any) => any> =
T extends (...args: any) => infer R ? R : any;

Он принимает тип функции и выводит (infer) тип возвращаемого значения. Ключевые моменты:

  • Работает только с типами функций, не с экземплярами
  • Для generic-функций возвращает тип с конкретным generic (если он известен на момент использования)
  • Не работает с перегруженными функциями - берёт последнюю сигнатуру
  • С async-функциями возвращает Promise<T>, а не сам T

На практике

Основные сценарии использования:

  • Типизация результатов вызова API без дублирования типов
  • Создание типов на основе существующих функций в библиотеках
  • Упрощение рефакторинга - изменение функции автоматически обновляет зависимые типы
  • Работа с HOC и декораторами, где нужно сохранить тип возврата

Ограничения:

  • Нельзя использовать с конструкторами (для них есть InstanceType)
  • Не работает с функциями, имеющими несколько перегрузок
  • Для generic-функций нужно явно указывать тип аргументов

Пример кода

TYPESCRIPT
// Базовая функция
function createUser(name: string, age: number) {
return { id: Date.now(), name, age };
}
type User = ReturnType<typeof createUser>;
// User = { id: number; name: string; age: number }
// Async функция
async function fetchData(url: string) {
const response = await fetch(url);
return response.json();
}
type Data = ReturnType<typeof fetchData>;
// Data = Promise<any>
// Generic функция
function identity<T>(value: T): T {
return value;
}
type Result = ReturnType<typeof identity<string>>;
// Result = string
// С перегрузками - берётся последняя сигнатура
function parse(input: string): number;
function parse(input: string[]): string[];
function parse(input: string | string[]): number | string[] {
return typeof input === 'string' ? parseInt(input) : input;
}
type ParseResult = ReturnType<typeof parse>;
// ParseResult = number | string[] (последняя сигнатура)

Как отвечать на собеседовании

Начни с краткого определения: это utility type для извлечения типа возврата функции. Приведи простой пример с typeof. Затем объясни механизм через infer. Упомяни ограничения: перегрузки, конструкторы, generic-функции. Покажи практический кейс - например, типизацию ответа от API. Если спросят про альтернативы - упомяни Awaited<ReturnType<T>> для async-функций. Не углубляйся в реализацию условных типов, если не просят.

Что проверяет интервьюер

  • Понимание системы типов TypeScript и utility types
  • Умение работать с условными типами и infer
  • Знание ограничений и edge cases (перегрузки, async, generic)
  • Практическое применение для уменьшения дублирования кода
  • Понимание разницы между типами и runtime-значениями

Типичные ошибки

  • Попытка использовать ReturnType с экземпляром функции вместо typeof
  • Ожидание, что ReturnType с async-функцией вернёт не Promise, а сам тип
  • Использование с перегруженными функциями без учёта последней сигнатуры
  • Применение к конструкторам (нужен InstanceType)
  • Забывание, что generic-функции требуют явной подстановки типа

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

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