typescript - 我可以将映射元组类型用于 juxt 函数吗?
juxt 调用一组函数以返回一组值。文档:ramda clojure
我正在尝试编写这个的以数据为先的版本,不使用覆盖,但我无法弄清楚如何将函数元组映射到它们的返回值。这是我现在的写法:
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))
}
它抱怨(以及其他抱怨)
Type 'Fs[K]' does not satisfy the constraint '(...args: any) => any'.
在 TypeScript 中这是可能的吗?
答案#1
考虑在这种情况下使用函数重载:
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)]
)
操场
我添加了条件类型 Fns[K] extends Fn ? ReturnType<Fns[K]> : never 只是为了确保 TypeScript 知道 Fns[K] 是一个函数
你可以在这里找到关于推断 [].map 返回类型的更多信息。这一更改曾被合并,然后又被撤回。
为了更好地理解这个语法 [...Fns],请参阅可变元组类型的文档
答案#2
我不确定为什么 ReturnType 不起作用。不过,这里有一个替代方法:
type JuxtFn<T> = (x: T) => any
function juxt<T, FS extends readonly JuxtFn<T>[]>(
x: T,
fns: FS,
) {
return fns.map(fn => fn(x)) as unknown as { [K in keyof FS]: FS[K] extends (x:any)=>infer X ? X : never}
这里是完整的游乐场。那有帮助吗?
