← Назад к вопросам

Что такое утилита Parameters?

1.8 Middle🔥 81 комментариев
#TypeScript

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Утилита Parameters в TypeScript

Parameters — это встроенная утилита типов (utility type) в TypeScript, которая извлекает типы параметров функции в виде кортежа (tuple). Это позволяет получить информацию о том, какие аргументы принимает функция, и использовать эту информацию для типизации.

Основное назначение

Parameters используется для:

  1. Извлечения типов параметров из сигнатуры функции
  2. Создания типобезопасных обёрток и декораторов
  3. Работы с функциональным программированием — HOC, middleware
  4. Валидации аргументов на уровне типов

Синтаксис и примеры

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

Простой пример:

function greet(name: string, age: number): void {
  console.log(`${name} is ${age} years old`);
}

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

// Можно обращаться к отдельным параметрам
type FirstParam = Parameters<typeof greet>[0]; // string
type SecondParam = Parameters<typeof greet>[1]; // number

Практические примеры

1. Создание типа для аргументов функции

function calculateTotal(amount: number, tax: number, discount: number): number {
  return amount + tax - discount;
}

type CalcArgs = Parameters<typeof calculateTotal>;
// CalcArgs = [amount: number, tax: number, discount: number]

// Использование при создании другой функции
function validateCalculateArgs(args: CalcArgs): boolean {
  return args.every(arg => typeof arg === 'number' && arg >= 0);
}

2. Создание функции-обёртки (wrapper)

function logAndExecute<T extends (...args: any[]) => any>(
  fn: T,
  ...args: Parameters<T>
): ReturnType<T> {
  console.log('Функция вызвана с аргументами:', args);
  const result = fn(...args);
  console.log('Результат:', result);
  return result;
}

function add(a: number, b: number): number {
  return a + b;
}

logAndExecute(add, 5, 3); // Правильно типизировано
logAndExecute(add, 'a', 'b'); // Ошибка типа!

3. Декоратор для функций

function retry<T extends (...args: any[]) => Promise<any>>(
  fn: T,
  maxAttempts: number = 3
): (...args: Parameters<T>) => Promise<ReturnType<T>> {
  return async (...args: Parameters<T>) => {
    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
      try {
        return await fn(...args);
      } catch (error) {
        if (attempt === maxAttempts) throw error;
        console.log(`Попытка ${attempt} не удалась, повторяю...`);
      }
    }
  };
}

async function fetchData(url: string, timeout: number): Promise<string> {
  // ...
}

const retryFetch = retry(fetchData);
// retryFetch имеет правильные типы аргументов!
await retryFetch('https://api.example.com', 5000);

4. Middleware в Express

import express, { Request, Response, NextFunction } from 'express';

function createMiddleware<T extends (req: Request, res: Response, next: NextFunction, ...args: any[]) => any>(
  handler: T
) {
  return (...args: Parameters<T>) => {
    const [req, res, next] = args;
    try {
      handler(...args);
    } catch (error) {
      next(error);
    }
  };
}

5. Кортеж параметров в функции высшего порядка

type Callable = (...args: any[]) => any;

function pipe<T extends Callable[]>(...fns: T) {
  return function(...args: Parameters<T[0]>) {
    let result: any = fns[0](...args);
    for (let i = 1; i < fns.length; i++) {
      result = fns[i](result);
    }
    return result;
  };
}

const add = (a: number, b: number) => a + b;
const double = (n: number) => n * 2;
const toString = (n: number) => String(n);

const pipeline = pipe(add, double, toString);
pipeline(3, 4); // ((3 + 4) * 2).toString()

Parameters vs Return Type

TypeScript предоставляет несколько полезных утилит для работы с функциями:

function example(a: string, b: number): boolean {
  return true;
}

// Извлечение параметров
type Args = Parameters<typeof example>; // [a: string, b: number]

// Извлечение типа возврата
type RetVal = ReturnType<typeof example>; // boolean

// Конструктор
type ConstructorArgs = ConstructorParameters<typeof Date>;

Работа с перегруженными функциями

interface Calculator {
  (a: number, b: number): number;
  (a: string, b: string): string;
}

const calc: Calculator = (a: any, b: any) => a + b;

type CalcParams = Parameters<Calculator>;
// CalcParams = [a: number, b: number] | [a: string, b: string]

Практические советы

  1. Комбинируйте с ReturnType для полной типизации функций
  2. Используйте для создания обёрток — это гарантирует совместимость сигнатур
  3. Проверяйте совместимость функций перед их передачей
  4. Применяйте при создании middleware и декораторов
  5. Используйте Parameters<typeof func> для извлечения типов из существующих функций

Заключение

Parameters — это мощная утилита TypeScript для работы с функциональным программированием. Она позволяет создавать типобезопасный код, когда функции передаются как аргументы, особенно полезна при создании обёрток, декораторов, middleware и других паттернов высшего порядка. Понимание этой утилиты критически важно для написания масштабируемого TypeScript кода.