I want to write a generic function that accepts variable number of arguments that may have different types and returns a tuple based on those arguments.
Here is an example in JavaScript:
function evaluate (...fns) {
return fns.map(fn => fn())
}
evaluate(
() => 10
) // [ 10 ]
evaluate(
() => 10,
() => 'f',
() => null
) // [ 10, 'f', null ]
And in TypeScript I need to somehow convert the spread argument tuple to a resulting one:
function evaluate<T1, T2 ... Tn> (
...fns: [() => T1, () => T2 ... () => Tn]
): [T1, T2 ... Tn] {
return fns.map(fn => fn()) as [T1, T2 ... Tn]
}
evaluate(
() => 10
) // [ 10 ]: [number]
evaluate(
() => 10,
() => 'f',
() => null
) // [ 10, 'f', null ]: [number, string, null]
I've tried a naive approach of creating an overload for all reasonable lengths of tuple:
function evaluate<T1> (
fn1: () => T1
): [T1]
function evaluate<T1, T2> (
fn1: () => T1,
fn2: () => T2
): [T1, T2]
function evaluate<T1, T2, T3> (
fn1: () => T1,
fn2: () => T2,
fn3: () => T3
): [T1, T2, T3]
function evaluate<T1, T2, T3> (
...fns: Array<(() => T1) | (() => T2) | (() => T3)>
): [T1] | [T1, T2] | [T1, T2, T3] {
return fns.map(fn => fn()) as [T1] | [T1, T2] | [T1, T2, T3]
}
But it looks horribly, doesn't scale well and causes issues with a more complex function body.
Is there any way this could be done dynamically? Thanks!