【问题标题】:Can I used mapped tuple types for the juxt function?我可以为 juxt 函数使用映射元组类型吗?
【发布时间】:2021-12-05 02:31:31
【问题描述】:

juxt 调用一个函数数组来返回一个值数组。文档:ramdaclojure

我正在尝试键入没有覆盖的数据优先版本,但我不知道如何map the tuple of functions to their return values。这就是我所拥有的:

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 中可行吗?

【问题讨论】:

    标签: typescript typescript-generics ramda.js


    【解决方案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)]
    )
    

    Playground

    我添加了条件类型 Fns[K] extends Fn ? ReturnType&lt;Fns[K]&gt; : never 只是为了确保 TypeScript Fns[K] 是一个函数

    您可以找到有关推断[].map here 的返回类型的更多信息。这被合并然后恢复。

    为了更好地理解这个语法[...Fns],请查看variadic tuple types的文档

    【讨论】:

    • 哇!那么是否需要在这里使用重载,或者只是让它更干净?我不反对超载,我只是好奇。
    • 我想说,如果函数有迭代器,当你想推断返回类型时,最首选的方法是重载你的函数。此外,您始终可以编写类型断言。
    • 谢谢!我看到[...Fns] 是必需的,它不能代替Fns。您是否有在类型定义中使用扩展/休息表示法的指针? (谷歌搜索发现了很多关于 rest 参数的例子,但我认为这是不同的。)
    • 对不起,没有提及。谷歌:打字稿可变元组类型
    【解决方案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}
    

    完整的游乐场here。这有帮助吗?

    【讨论】:

    • 谢谢,有替代品真是太好了……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-19
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多