I want to write a call
function:
function call<F extends (...arg: any) => any, P extends Parameters<F>>(
fn?: F,
...arg: P
): ReturnType<F> | undefined {
if (fn) return fn(...arg) // Type 'P' must have a '[Symbol.iterator]()' method that returns an iterator
}
const fn = (a: string) => {}
// automatically infer `fn` arguments type
call(fn, )
what should I do?
CodePudding user response:
This is a tricky one, but the solution is not.
You have to ensure the typescript that args is iterable. You can do that like manually saying to him - Hey this will be an array, believe me
function call<F extends (...arg: any) => any, P extends Parameters<F>>(
fn?: F,
...args: P
): ReturnType<F> | undefined {
if (fn){
// here is the ugly hint to typescript
return fn(...(args as any[]))
}
return undefined;
}
CodePudding user response:
Have you considered using apply
as a workaround?
function call<F extends (...arg: any) => any, P extends Parameters<F>>(
fn?: F,
...arg: P,
): ReturnType<F> | undefined {
if (fn) return fn.apply(undefined, arg);
return undefined;
}