Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Утилита Parameters в TypeScript
Parameters — это встроенная утилита типов (utility type) в TypeScript, которая извлекает типы параметров функции в виде кортежа (tuple). Это позволяет получить информацию о том, какие аргументы принимает функция, и использовать эту информацию для типизации.
Основное назначение
Parameters используется для:
- Извлечения типов параметров из сигнатуры функции
- Создания типобезопасных обёрток и декораторов
- Работы с функциональным программированием — HOC, middleware
- Валидации аргументов на уровне типов
Синтаксис и примеры
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]
Практические советы
- Комбинируйте с ReturnType для полной типизации функций
- Используйте для создания обёрток — это гарантирует совместимость сигнатур
- Проверяйте совместимость функций перед их передачей
- Применяйте при создании middleware и декораторов
- Используйте
Parameters<typeof func>для извлечения типов из существующих функций
Заключение
Parameters — это мощная утилита TypeScript для работы с функциональным программированием. Она позволяет создавать типобезопасный код, когда функции передаются как аргументы, особенно полезна при создании обёрток, декораторов, middleware и других паттернов высшего порядка. Понимание этой утилиты критически важно для написания масштабируемого TypeScript кода.