如何在Typescript中通用地转换函数的返回类型?

时间:2018-10-12 14:11:21

标签: typescript generics

我有一个REST API库,它为其所有功能返回Promise<string>。我想编写一个通用包装函数来包装API函数,解析JSON,并返回使用template参数键入的数据。

我有一些基本可行的方法,但是由于https://github.com/Microsoft/TypeScript/issues/16597的原因,我不得不设法做到这一点:

type Args<F> = F extends (...args: infer A) => any ? A : never

export function apiCall<T>() {
  return function<F extends (...args: any[]) => Promise<string>>(fn: F) {
    return function(...args: Args<F>): Promise<T> {
      return fn(...args).then(JSON.parse)
    }
  }
}

然后您像这样创建包装函数:

const wrapper = apiCall<ReturnType>()(apiFunction)

这似乎应该是单线的。我真的不喜欢仅仅为了满足类型系统而添加额外的函数调用。这里的困难是保持相同的参数类型,但更改返回类型。有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

不幸的是,当前您需要使用额外的函数方法。 Typescript不允许部分参数推断。您可以让编译器推断类型,也可以指定它们,但不能将两者结合使用(我们可以省略具有默认值的类型参数,但是这对我们没有帮助,因为如果我们指定一个参数并且使用默认值,则会使用默认值同样需要对这些参数进行推断)

幸运的是,您无需等待很长时间即可使用此功能。如ticket中所述,打字稿3.2将对此提供支持。如果按照当前的说明实施,则可以编写

const wrapper = apiCall<ReturnType, *>(apiFunction)

注意:此功能至少滑了一次,我们将看看它是否已在3.2(计划于2018年11月)中实现