Initially, I faced a challenge when trying to implement a function similar to mapDispatchToProps
in Redux. I struggled with handling an array of functions (action creators) as arguments, but managed to come up with a workaround that works, although it feels hacky. I'm curious if there's a better way to approach this.
The issue I encountered was that the return type didn't preserve types for each item; instead, it generalized them into a union.
Update: the problem lies in maintaining parameter types for each function within the resulting array.
In essence, the code below should have no errors:
type F = (...x: any[]) => any
type Wrap<T extends F> = (...x: Parameters<T>) => void
const wrap = (fn: any) => (...a: any) => { fn(...a)}
// current solution that seems to work
// issue is with K being too wide (number | string | symbol) for array index which causes suppression
// // @ts-expect-error
// function main<Fs extends readonly F[]>(fs: Fs): {[K in keyof Fs]: Wrap<Fs[K>]}
// TODO: desired solution, not yet completed: every item in `fs` should be wrapped with `Wrap`
function main<Fs extends readonly F[]>(fs: Fs): [...Fs]
function main(fs: any) { return fs.map(wrap) }
const n = (x: number) => x
const s = (x: string) => x
const fs = main([n, s] as const)
// TESTING PARAMETER TYPES
fs[0](1)
fs[1]('1')
// @ts-expect-error
fs[0]('1')
// @ts-expect-error
fs[1](1)
// TESTING RETURN TYPES
const _1: void = fs[0](1)
const _2: void = fs[1]('1')
// @ts-expect-error
const _3: number = fs[0](1)
// @ts-expect-error
const _4: string = fs[1]('1')
P.S: There is an open GitHub issue related to the problem with my initial solution (#1) as of August 25, 2020. It pertains to the width of `keyof ArrayType`, rather than variadic tuple types.