我编写了这个简单的合成函数,它工作得很好。然而,为了确保类型安全,我不得不使用泛型来向编译器提供类型提示,尽管可以很容易地推断出"upperCaseAndLog“的签名。
const compose = <T, R>(...fns: Array<(a: any) => any>) => (a: T): R =>
fns.reduce((b, f) => f(b), a);
const greet = (s: string) => "Hello " + s;
const toUpperCase = (s: string) => s.toUpperCase();
const log = console.log;
const upperCaseAndLog = compose<string, void>(
greet,
toUpperCase,
log
);
upperCaseAndLog("bill");
我是不是错过了什么,有没有更优雅的方法来实现同样的目标?我假设像F#或Haskell这样的语言可以在没有任何额外信息的情况下推断类型。
发布于 2018-11-07 07:01:13
类型记录不能推断这样的链接类型(链接的意思是函数的参数依赖于前一个函数的结果)。
您甚至不能以足够通用的方式定义compose的签名,以至于它可以用于许多函数。我们可以做的是定义可以接受给定数量的函数的重载:
type Fn<A, R> = (a: A) => R // just to be a bit shorter in the compose signature, you can use teh function signature directly
function compose<T, P1, P2, R>(fn1: Fn<T, P1>, fn2: Fn<P1, P2>, f3: Fn<P2, R>) : Fn<T, R>
function compose<T, P1, R>(fn1: Fn<T, P1>, f2: Fn<P1, R>) : Fn<T, R>
function compose(...fns: Array<(a: any) => any>) {
return function (a: any) {
return fns.reduce((b, f) => f(b), a);
}
}
const greet = (s: string) => "Hello " + s;
const toUpperCase = (s: string) => s.toUpperCase();
const log = console.log;
const upperCaseAndLog = compose(
greet,
toUpperCase,
log
);
upperCaseAndLog("bill");//(a: string) => voidhttps://stackoverflow.com/questions/53182284
复制相似问题