Оставшиеся параметры (...rest) в TypeScript
Есть функция createRequest, которая принимает в себя функцию func, и возвращает асинхронную функцию action, которая внутри себя будет вызывать функцию func. Как сделать так, что бы функция action принимала в себя только параметры func, будто вызывается непосредственно функция func?
function createRequest(func: Function): Function {
// входящие параметры функции action должны соответствовать
// входящим параметрам функции func
return async function action(...args: any) {
// other code...
func(...args);
// ...other code
}
}
Например:
function A (a: number, b: string) {
return [a, b];
}
const B = createRequest(A);
B(1, 'a'); // корректный вызов, передающиеся параметры правильного типа
B(1, 2); // некорректный вызов, typescript должен выдавать ошибку типов
На данный момент код работает, но нужно проверка типов TypeScript.
Наткнулся на Parameters<Type>, однако мне не совсем понятно, как это применить, и подходит ли это вообще.
Ответы (2 шт):
Для использования Parameters<T>, нужно чтобы T был совместим с сигнатурой (...args: any): any.
Поэтому в данном случае не получится использовать тип Function.
Однако можно сделать функцию createRequest шаблонной
createRequest<T>
и добавить, что T расширяет (...args: any): any
createRequest<T extends (...args:any)=>any>(func: T)
Так же можно добавить тип возвращаемого значения
function createRequest<T extends (...args:any)=>any>(func: T): (...args:Parameters<T>)=>Promise<void> {
Теперь, для возвращаемой функции достаточно просто указать тип параметров:
return async function action(...args: Parameters<T>) {
теперь, чтобы заработал
func(...args);
Нужно указать, что тип у args - массив, для этого нужно изменить либо в обертке
createRequest<T extends (...args:any[])=>any>(func: T)
либо в возвращаемой функции
return async function action(...args: Parameters<T>[]) {
Итоговый код может выглядеть так:
function createRequest<T extends (...args:any[])=>any>(func: T): (...args:Parameters<T>)=>Promise<void> {
// входящие параметры функции action должны соответствовать
// входящим параметрам функции func
return async function action(...args: Parameters<T>) {
// other code...
func(...args);
// ...other code
}
}
function A (a: number, b: string) {
return [a, b];
}
const B = createRequest(A);
B(1, 'a'); // корректный вызов, передающиеся параметры правильного типа
B(1, 2); // некорректный вызов, typescript должен выдавать ошибку типов
function createRequest<Args extends any[]>(func: (...args: Args) => void) {
return async function action(...args: Args) {
func(...args);
}
}
function f(a: number, b: string) {
return [a, b];
}
const g = createRequest(f);
g(1, 'a'); // ok
g(1, 2); // Argument of type 'number' is not assignable to parameter of type 'string'.