遗憾的是,TypeScrip缺乏对instantiating或specifying的直接支持,即在类型级别对generic函数的类型参数.对此至少有一个开放的特性请求;请参阅microsoft/TypeScript#44521,但到目前为止它还没有实现.请注意,TypeScrip 4.7引入了对instantiation expressions的支持,这允许您在不调用泛型函数value的情况下为其指定类型参数,但没有类似的方法可以纯粹在类型级别上这样做.因为F
只是一个函数类型,而不是函数值,所以您不能执行类似F<A>
的操作.
请注意,语法F<A>
将是不明确的,因为不清楚A
是否应该是泛型call signature的类型参数(您在这里所要求的),或者它是否应该是泛型type的类型参数(通常被认为是这样).事实上,由于F
本身是通用的,这两项工作都不是...Typescript 也缺少microsoft/TypeScript#1213分所要求的higher kinded types分.因此,无论如何,F<A>
在TS5.1的Typescript 中是根本不可能的.
正如前面提到的,TypeScrip对泛型类型或泛型函数类型的任意操作没有太多直接支持.在一些特定情况下,您可以获得一些高阶行为,但它们本质上是硬编码的启发式特性,并不是所有地方都完全支持它们.实例化表达式曾经是这样的功能.
还有higher order type inference from generic functions个.这实际上可以用来使您的示例代码工作:
function compose<A, R>(fn: (a: A) => R, val: A): R {
return fn(val)
}
interface FooReturn<T> { foo: T }
function foo<T>(val: T): FooReturn<T> {
return { foo: val }
}
let fooRes = compose(foo, '')
// let fooRes: FooReturn<string>
interface BarReturn<T> { bar: T }
function bar<T>(val: T): BarReturn<T> {
return { bar: val }
}
let barRes = compose(bar, 1)
// let barRes: BarReturn<number>
但它很脆弱;您必须将泛型函数直接传递给compose()
.不能使用泛型方法或泛型函数的任何其他更复杂的嵌套来传递对象.这被认为是打印脚本的设计限制,如第microsoft/TypeScript#49505条所述.因此,尽管这种情况的某些情况可以得到充分处理,但总体问题仍然没有得到解决.
Playground link to code个