2

I'm trying to create a TypeScript function that accepts an array and returns a new function where the arguments have the types of the array.

In other words, it should be something like this:

type MyFunc = {
    <A>(arg: [A]): ((arg0: A) => any)
    <A, B>(arg: [A, B]): ((arg0: A, arg1: B) => any)
    <A, B, C>(arg: [A, B, C]): ((arg0: A, arg1: B, arg2: C) => any)
}

But for a variable number of inputs

Concrete examples

Here's some concrete examples (even though I'm looking for the general case):

type MyFuncA = (arg: [number]) => ((arg0: number) => any)
type MyFuncB = (arg: [string]) => ((arg0: string) => any)
type MyFuncC = (arg: [number, string]) => ((arg0: number, arg1: string) => any)
type MyFuncD = (arg: [number, string, bool]) => ((arg0: number, arg1: string, arg2: bool) => any)

1 Answer 1

3

I think the simplest would be:

type MyFunc = <T extends readonly unknown[]>(args: T) => (...args: T) => unknown

It accepts an array of anything as T, and spreads that array over the arguments of the returned function with ...args: T.

Usage:

declare const fn: MyFunc // pretend this function exists

const testA = fn([1, 'asd', true] as const)
// (args_0: 1, args_1: "asd", args_2: true) => unknown

Just note the as const is used here to force the argument to be a tuple type [number, string, boolean], rather than an array type of (number | string | boolean)[], since it needs the tuple to infer the order of the arguments. But providing any tuple type should work fine.

If you don't pass in a tuple, you will provide a spread array type which is better than nothing but not as useful:

const testA = fn([1, 'asd', true])
// (...args: (string | number | boolean)[]) => unknown

Playground


If you have a tuple type with names for each element, those names will even be reported as the argument names of the function!

const myTuple: [num: number, str: string, isAwesome: boolean] = [1, 'asd', true]
const testA = fn(myTuple)
// (num: number, str: string, isAwesome: boolean) => unknown

Which is neat.

Playground

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.