Что такое ReturnType и Parameters в TypeScript?

MiddleTypeScript · Frontend·Обновлено 14 августа 2026
Коротко
ReturnType и Parameters — встроенные utility types, которые извлекают из сигнатуры функции тип возвращаемого значения и типы параметров (в виде кортежа) соответственно, чтобы не дублировать эти типы вручную.

Что это такое

ReturnType<T> и Parameters<T> — встроенные условные (conditional) типы TypeScript из группы utility types. Они позволяют извлекать типы из сигнатуры функции без ручного дублирования кода.

  • ReturnType<T> — извлекает тип возвращаемого значения функции T.
  • Parameters<T> — извлекает типы параметров функции T в виде кортежа (tuple).

Как они устроены внутри

Оба типа реализованы через infer в условных типах (примерно так выглядят в lib.es5.d.ts):

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

type Parameters<T extends (...args: any) => any> =
  T extends (...args: infer P) => any ? P : never;

infer позволяет TypeScript «вывести» и захватить часть типа прямо во время сопоставления с шаблоном внутри условного типа.

Зачем это нужно

Главная причина использования — избежать дублирования типов. Если сигнатура функции меняется, отдельно объявленный интерфейс не нужно обновлять вручную — тип выводится автоматически.

Типичные сценарии:

  • типизация результата функции из внешней библиотеки без явно экспортированного типа;
  • обёртки, декораторы, HOC, которым нужно повторить сигнатуру оборачиваемой функции;
  • типизация моков в тестах на основе реальной функции;
  • generic-утилиты, где важно сохранить связь между аргументами и результатом.

Пример

function createUser(name: string, age: number) {
  return { id: 1, name, age };
}

type User = ReturnType<typeof createUser>;
// { id: number; name: string; age: number }

type CreateUserArgs = Parameters<typeof createUser>;
// [name: string, age: number]

Обратите внимание на typeof createUser: сам ReturnType работает с типами функций, а не со значениями, поэтому для объявленной функции нужен оператор typeof.

Похожие utility types

  • ConstructorParameters<T> — параметры конструктора класса.
  • InstanceType<T> — тип экземпляра, который возвращает конструктор.
  • ThisParameterType<T> / OmitThisParameter<T> — работа с типом this функции.
  • Awaited<T> — разворачивает Promise, часто применяется вместе с ReturnType для async-функций.

Ограничения

  • Работают только с типами функций — на произвольном объекте не сработают.
  • Parameters всегда возвращает кортеж, даже для функции без параметров — будет [].
  • Для перегруженных (overloaded) функций ReturnType берёт тип из последней сигнатуры перегрузки.
  • Не разворачивают Promise автоматически: ReturnType для async function вернёт Promise<T>, а не T — нужен Awaited<ReturnType<typeof fn>>.

Что хочет услышать интервьюер

Кандидат понимает, что это utility types на основе conditional types и ключевого слова infer

Может объяснить, зачем при передаче функции нужен оператор typeof

Знает, что Parameters возвращает кортеж (tuple), а не объект

Упоминает связанные типы: ConstructorParameters, InstanceType, Awaited

Понимает нюанс с async-функциями и необходимость Awaited для разворачивания Promise

Пример: Базовое использование ReturnType и Parameters

function createUser(name: string, age: number) {
  return { id: 1, name, age };
}

// Тип объекта, который возвращает функция
type User = ReturnType<typeof createUser>;
// { id: number; name: string; age: number }

// Кортеж типов параметров функции
type CreateUserArgs = Parameters<typeof createUser>;
// [name: string, age: number]

function callWithSavedArgs(...args: CreateUserArgs): User {
  return createUser(...args);
}

Пример: Собственная реализация через infer

// Упрощённая реализация ReturnType и Parameters
type MyReturnType<T extends (...args: any) => any> =
  T extends (...args: any) => infer R ? R : never;

type MyParameters<T extends (...args: any) => any> =
  T extends (...args: infer P) => any ? P : never;

// infer выводит и «захватывает» часть типа при сопоставлении
type Fn = (a: string, b: number) => boolean;

type Result = MyReturnType<Fn>; // boolean
type Args = MyParameters<Fn>;   // [a: string, b: number]

Пример: Работа с async-функциями и Awaited

async function fetchUser(id: number) {
  return { id, name: "Anna" };
}

// Без Awaited получим Promise<{...}>, а не сам объект
type RawResult = ReturnType<typeof fetchUser>;
// Promise<{ id: number; name: string }>

// Awaited «разворачивает» Promise до реального значения
type UnwrappedResult = Awaited<ReturnType<typeof fetchUser>>;
// { id: number; name: string }

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

Передают саму функцию как значение, а не её тип через typeof

Путают ReturnType<typeof fn> с типом самой переменной fn

Ожидают, что ReturnType автоматически развернёт Promise у async-функций

Не понимают, что infer работает только внутри условных типов, и пытаются объяснить механизм неверно

Путают Parameters с рантайм-объектом arguments внутри функции

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее