Yassine K
Yassine K

Reputation: 348

Typescript generic type unknown arguments count

I'm trying to make a function with a generic type that takes a function, an array of its arguments, then apply them to it, but typescript doesn't interpret the args type correctly

  const animate = async <P, A>(
    action: (payload: P) => any,
    algorithm: (...args: A[]) => P[],
    args: A[]
  ) => {
    if (state.playing) return;
    dispatch(togglePlaying());
    const sequence = algorithm(...args);
    for (let element of sequence) {
      await delay(1);
      dispatch(action(element));
    }
    dispatch(togglePlaying());
  };

Here is the error I get when trying to use it

Argument of type '(rows: number, cols: number, startCell: Coordinates, endCell: Coordinates) => GridT[]' is not assignable to parameter of type '(...args: (number | Coordinates)[]) => GridT[]'

Upvotes: 1

Views: 3102

Answers (1)

ftm
ftm

Reputation: 385

What you need is the Parameters<Type> type: https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype

Constructs a tuple type from the types used in the parameters of a function type Type.

Then, you can define your function like this:

const animate = async <P, F extends (...args: any[]) => P[]>(
    action: (payload: P) => any,
    algorithm: F,
    args: Parameters<F>
) => {
    // blah
}

As your error message shows, if you define the type of algorithm as (...args: A[]) => P[], you're essentially saying every argument is of the same type (in your case number | Coordinates), so when you try to pass in a function of type (rows: number, cols: number, startCell: Coordinates, endCell: Coordinates) => GridT[] it doesn't match.

Upvotes: 3

Related Questions