Typescript: How does `Parameters<F>` keep arguments' names?

Viewed 223

Consider the following piece of code:

const f = (a: number, b?: string) => 2;

type ParametersOfF = Parameters<typeof f>; // [number, string?]
type AsTuple = [number, string?]; // [number, string?]

declare function g(...args: ParametersOfF): number; // function g(a: number, b?: string): number !!!
declare function h(...args: AsTuple): number; // function h(args_0: number, args_1?: string): number

So ParametersOfF and AsTuple are the same type. But when I define functions which take args these 2 tuples, g have well defined argument names a and b, while h has args_0 & args_1.

Hence the title of this post: Parameters<F> is not a simple tuple, it contains also the names of each element in said tuple. Looking at how Parameters is defined doesn't help, it's quite simple. So what's the magic?

1 Answers

The reason has to do with compiler internals not so much with the Parameters type itself. Any similar conditional type you write will preserve parameter names.

For tuples extracted from parameters , the compiler keeps a reference to the original parameter each tuple item was extracted from. When the tuple is spread back to a function the original name is used.

This association is not something directly visible from the type system and there is no way to set this tuple item name, it's a hidden property of the tuple.

Related