【发布时间】:2015-05-11 06:42:54
【问题描述】:
使用 Typescript 1.4,假设我有一个带有签名的高阶函数:
interface F<A,B> {
(a: (...x:any[]) => A): (...x:any[]) => B
}
函数“F”采用函数“a”,该函数具有一组参数“x”。函数“F”返回一个与函数“a”具有完全相同的参数集的新函数。
我一直在尝试找到一种在 Typescript 中表达这一点的方法,但我做不到。例如:
interface F<X extends Array<any>,A,B> {
(a: (...x:X) => A): (...x:X) => B
}
编译器只是抱怨:error TS2370: A rest parameter must be of an array type.
虽然这感觉不对,即使它确实编译了。我想我真的需要这样的东西:
interface F<X extends Tuple,A,B> {
(a: (...x:X) => A): (...x:X) => B
}
有人知道目前 Typescript 是否可以实现这种事情(撰写本文时为 1.4)?或者有什么建议?
示例:
(注意:这不是我的实际用例,我只是在这里使用日志作为一个简单的例子——请不要专注于这方面)
// a higher-order function that takes any function and
// returns a new function which takes the same args
// passing them to the original fn and logging the args along with the result
function f(a:(...x:any[]) => any): (...x:any[]) => void {
return (...x:any[]) => {
console.log('('+x.join(',')+') => ', a.apply(undefined, x));
}
}
function a(j:string, k:number): boolean {
return j === String(k);
}
var b = f(a);
b("1", 1);
b("a", 2);
控制台输出:
(1,1) => true
(a,2) => false
所以这可行,但派生函数“b”具有以下隐含签名:
(...x:any[]) => void
理想情况下,我希望它具有与函数“a”相同的参数,即:
(j: string, k: number) => void
我知道我可以明确地定义它,但它非常冗长而且一点也不理想,有点违背了首先拥有强类型的意义:
var b: (j:string, k:number) => void = f(a);
【问题讨论】:
标签: generics functional-programming typescript