如何获得函数的正确返回类型,其中返回类型取决于泛型参数?
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
答案 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-circuit到true
和{{ 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类型。