question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

When trying to use mapped tuples as rest parameters error 'A rest parameter must be of an array type' given

See original GitHub issue

TypeScript Version: 3.2

Search Terms: mapped tuples rest

Code

type FuncParams<T> = T extends (...args: infer P) => any ? P : never;
type Stringify<T> = {
    [K in keyof T]: string;
};
type Optional<T> = {
    [K in keyof T]?: T[K];
};

type ThreeParamFunc = (paramOne: string, paramTwo: number, paramThree: boolean) => void;

type Params = FuncParams<ThreeParamFunc>; // [string, number, boolean]
type StringParams = Stringify<FuncParams<ThreeParamFunc>>; // [string, string, string]
type OptionalParams = Optional<FuncParams<ThreeParamFunc>>; // [string?, number?, boolean?]

function doStuff<T>(func: T, ...params: FuncParams<T>) { // works fine
}

function doOptionalStuff<T>(func: T, ...params: Optional<FuncParams<T>>) { // A rest parameter must be of an array type.
}

function doStringStuff<T>(func: T, ...params: Stringify<FuncParams<T>>) { // A rest parameter must be of an array type.
}

Expected behavior: I should be able to use a mapped tuple as a rest param in a function

Actual behavior: I get the error A rest parameter must be of an array type.

Playground Link: Link

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:22
  • Comments:13 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
Roaderscommented, Oct 18, 2019

I’d be interested to hear why this is marked as a suggestion rather than a bug. As far as I see it you can usually use a tuple type as a function parameter but in this scenario (and other similarly complicated scenarios) it doesn’t work.

Can anyone explain why it doesn’t work in this case? I have tested my mapped type with function parameters and on it’s own it works fine as a rest param:

type FunctionParams<T> = T extends (...params: infer R) => any ? R : never;

type matchFunc<T> = (value: T) => boolean;

interface IMatcher<T>{
    match: matchFunc<T>;
    toString: () => string;
}

type MatchUnion<T> = matchFunc<T> | IMatcher<T>;

type ToMatchers<T extends any[]> = {
    [P in keyof T]: MatchUnion<T[P]>;
}

interface ISample{
    funcOne(one: string, two: number, three: boolean): true;
}

const sample: ISample = {} as any;

type MappedParams= ToMatchers<FunctionParams<ISample["funcOne"]>>;

function processMatchers(...params: MappedParams) {
}

playground

2reactions
Andaristcommented, Mar 8, 2019

Having the same problem - prepared a simpler repro (with artificial code ofc).

Real world use case would be to cover reselect’s createSelector API in generic manner - https://github.com/reduxjs/reselect#createselectorinputselectors--inputselectors-resultfunc

Read more comments on GitHub >

github_iconTop Results From Across the Web

A rest parameter must be of an array type - Stack Overflow
I have an odd error where the code below works, however the compiler is giving me an error. I believe C in ...args:...
Read more >
Rest parameters - JavaScript - MDN Web Docs
The rest parameter syntax allows a function to accept an indefinite number of arguments as an array, providing a way to represent variadic ......
Read more >
Rest parameters and spread syntax
Rest parameters and spread syntax. Many JavaScript built-in functions support an arbitrary number of arguments. For instance: Math ...
Read more >
A spread argument must either have a tuple type or be passed ...
A spread argument must either have a tuple type or be passed to a rest parameter. I am trying to do this, but...
Read more >
Tuple Types in TypeScript - geekAbyte
It will also touch on generic rest parameters and variadic tuple ... but arrays should contain the same types, and function arguments do...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found