ReturnType<T> и Parameters<T> — это utility types TypeScript, которые позволяют автоматически вывести тип возвращаемого значения функции (ReturnType) или массив типов её параметров (Parameters).
Это особенно удобно для обеспечения согласованности типов между разными частями приложения и для реализации generic-обёрток.
Пример использования:
function fn(a: number, b: string): boolean { return b.length > a; } type FnReturn = ReturnType<typeof fn>; // boolean type FnParams = Parameters<typeof fn>; // [number, string]
Нюансы с перегрузкой функций: При перегрузке функций ReturnType определяет последний вариант сигнатуры, а Parameters — все возможные перегрузки:
function overloaded(x: number): number; function overloaded(x: string): string; function overloaded(x: any): any { return x; } type OverRet = ReturnType<typeof overloaded>; // any type OverParams = Parameters<typeof overloaded>; // [any]
То есть, типизация utility типов не всегда "видит" все перегрузки, поэтому статичная типизация становится менее предсказуемой.
Можно ли с помощью ReturnType и Parameters получить типы всех возможных перегрузок кастомной функции, определяя каждую перегрузку по отдельности?
Ответ:
Нет. Utility типы ReturnType и Parameters анализируют только "объединённую" сигнатуру функции — как она описана для реализации. Они не позволяют получить типы каждой индивидуальной перегрузки — только итоговой реализованной сигнатуры.
Пример:
type P = Parameters<typeof overloaded>; // [any], а не [number], [string]
История
Разработчики написали обёртку aroundMethod, используя ReturnType<T> для типизации возвращаемого значения. При этом функция-обёртка применялась к перегруженной функции. Итог: typy были слишком общими (any), и при ошибках компилятор не сигнализировал несоответствие возвращаемых значений. Поздно обнаружили баг при работе с boolean'ами вместо string.
История
В попытке вывести параметры для множества API-функций через Parameters<T>, разработчик не учёл перегрузки методов. Возникла проблема с "ошибочными" типами, где вместо [string, number] ожидалось [any]. Unit-тесты не ловили эту ошибку из-за монтажа через реализацию, а реальные пользователи API получили баги на проде.
История
Мигрируя большой код с JavaScript на TypeScript, разработчики всё типизировали через ReturnType. Позже поняли, что реализация сильно отличается от декларации перегрузок. Из-за этого сценарии с ошибочными аргументами вызывали неожиданные runtime-исключения (например, TypeError: x is undefined).