如何根据泛型函数的泛型参数获取正确的返回类型

时间:2019-04-29 13:41:16

标签: typescript

如何获得函数的正确返回类型,其中返回类型取决于泛型参数?

function f1<T>(o: T) {
  return { a: o }
}

// I was hoping (n: number) would set T to number:
type T1 = typeof f1 extends (n: number) => infer R ? R : never // T1 is unknown

2 个答案:

答案 0 :(得分:3)

TypeScript当前在大多数higher kinded types的类型系统中都缺乏支持,这是表示常规函数类型上的操作所需要的。因此简短的回答是“抱歉,您不能这样做。”


解决方法通常包括手动指定您希望通用的具体类型,或者说服编译器通过模拟某些运行时效果进行必要的分析。很难从示例代码中知道您的确切用例是什么,因此以下变通办法似乎很愚蠢,但对于您的实际情况来说,可能可行。

对于前一种手动指定事物的情况,您的示例代码将变得相对无趣:

type T1 = { a: number };

对于后一种情况,假装有运行时代码,您可以执行以下操作:

const t1 = true as false || f1(null! as number);
type T1 = typeof t1; // {a: number}

我向编译器撒谎说true的类型为false,这意味着在运行时,表达式t1将从short-circuittrue和{{ 1}}永远不会被调用。但是在编译时,编译器认为它是f1(),因此期望false || f1(someNumber)的类型将是t1

有一个proposal允许您使用类型查询运算符{a: number}来处理任何表达式,而在实现了该表达式的世界中,您只需编写

typeof

并且没有发出任何运行时代码...但是该提议被拒绝,因此上面的代码是workaround for it


无论如何,对不起,您没有更好的答案。希望这有所帮助;祝你好运!

答案 1 :(得分:0)

我不确定原因,但以下内容对您来说可以正常工作

type f1<T> = (o: T) => { a: T }
type T1 = f1<number>

Typescript将f1视为值而不是类型,因此它无法在运行时之前创建T1类型。