Issue
juxt calls an array of functions to return an array of values. Docs: ramda clojure
I'm trying to type a data-first version of this without overrides, but I can't figure out how to map the tuple of functions to their return values. This is what I have:
type JuxtFn<T> = (x: T) => any
function juxt<T, Fs extends JuxtFn<T>[]>(
x: T,
fns: Fs,
): {[K in keyof Fs]: ReturnType<Fs[K]>} {
return fns.map(fn => fn(x))
}
It complains (among other complaints)
Type 'Fs[K]' does not satisfy the constraint '(...args: any) => any'.
Is this possible in TypeScript?
Solution
Consider using function overload for this case:
type JuxtFn<T> = (x: T) => any
function juxt<T, Fn extends JuxtFn<T>, Fns extends Fn[]>(
x: T,
fns: [...Fns],
): { [K in keyof Fns]: Fns[K] extends Fn ? ReturnType<Fns[K]> : never }
function juxt<T, Fs extends JuxtFn<T>[]>(
x: T,
fns: Fs,
) {
return fns.map(fn => fn(x))
}
// [string[], Promise<number>]
const result = juxt(
10,
[(v: number) => ['s'], (v: number) => Promise.resolve(42)]
)
I have added conditional type Fns[K] extends Fn ? ReturnType<Fns[K]> : never just to assure TypeScript that Fns[K] is a function
You can find more information about infering return type of [].map here. This was merged and then reverted.
In order to better understand this syntax [...Fns] please see documentation for variadic tuple types
Answered By - captain-yossarian
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.