Home > Back-end >  Using Parameters<F> infer arguments type
Using Parameters<F> infer arguments type

Time:10-23

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

Working playground

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;
}

Playground

  • Related