Jørgen Tvedt
Jørgen Tvedt

Reputation: 1274

How to type a variant of a function with no optional arguments - with mapped tuple

I try to make a typing for a function that has the exact same arguments that the source function, but where none are optional.

I tried to use a mapped tuple, using the logic:

type IFArgs = ArgsN<typeof getFunc>
type IMappedIFArgs = {[N in keyof IFArgs]-?: IFArgs[N]} // The -? removes "optionality"
const getFuncMandatory = <(...args: IMappedIFArgs) => string>getFunc // Error: IMappedIFArgs not a tuple...

Where ArgsN comes from the tsargs library, and is defined cleverly like this:

export type ArgsN<T extends (...args: any[]) => any> = T extends (...args: infer K) => any ? K : never;

According to the 3.1 documentation, the mapped type should also be a tuple, when the source is a tuple. This seems to be almost the case, when inspecting in VS Code - but not close enough for the compiler to accept it as an argument. Also, the length of the mapped type returns 2 | 3, not 3 - which makes sense, but is not what I want.

Any ideas how to make the mapped tuple a valid argument tuple? Any ideas on how to archive the same using other mechanisms would also be nice.

Upvotes: 1

Views: 100

Answers (1)

spender
spender

Reputation: 120450

A few of the types you define already exist within TypeScript.

I haven't investigated the differences between what's going on here and what you have, but this seems to work:

function getFunc(n:number,s?:string):void{}
type IFArgs = Parameters<typeof getFunc>
type IMappedIFArgs = Required<IFArgs>

const getFuncMandatory = getFunc as ((...args: IMappedIFArgs) => string)

See the definitions of these types to compare to your own implementation: Parameters, Required

Upvotes: 1

Related Questions