I'm using fetch-mock library to build my own utils.
When defining a new function and passing args to fetchMock.mock function, I get this error:
A spread argument must either have a tuple type or be passed to a rest parameter
export function mockRequest(...args: any) {
return fetchMock.mock(...args);
}
I could strictly define the amount of arguments, but would want to avoid it. Any suggestions how to keep ...args and make TypeScript happy?
I've tried various solutions such as using .apply and doing some casts as well but to no avail.
Problem
fetchMock.mockis typed to accept 0-3 arguments:– wheresrhys/fetch-mock/types/index.d.ts:L270-L294
An attempt is made to spread an array of
anyinto it.anywill not stop TypeScript from checking the potential length of the spread – it will only not check the type of the items in the tuple are acceptable for the function parameters. An example:TypeScript Playground
Solution
The error message tells you the solution (emphasis mine):
Let's explore both of them.
Passing to a rest parameter
If the function is typed to accept a rest parameter it works because rest parameters are essentially an infinite list of optional parameters. However, in your case, you don't have control of the interface of the library. Consequently, you'll have to use the other option.
Type the argument as a tuple
Tuples are a list that have two notable properties. They are:
Using
Parameters?TypeScript provides a utility function named
Parameterswhich constructs a tuple type from the types used in the parameters of the function passed to it, so in theory you could do this:TypeScript Playground
However at the time of writing,
Parametersonly returns the parameters from the last overload (see TypeScript issue 14107 and TypeScript issue 32164). In the above example,mockRequestwould be typed to accept no parameters because the last overload offetchMock.mockhas no parameters.Manual types
As lovely as it would've been to use
Parameters. It looks like we'll have to manually add types. Here's a working example:TypeScript Playground
For an underdetermined reason, TypeScript isn't able to narrow the type of
argstoOverload1with the conditionargs.length >= 2so a cast is necessary.