我定义了
pipe
和 compose
函数,每个函数都能够将两个函数组合成一个新函数,唯一的区别是应用于参数时的调用顺序。
这两个函数都是通用的,我希望我可以使乘积函数成为强类型,但有些东西是关闭的,并且结果函数类型被错误地推断出来。
问题:
function pipe<X, Y, Z>(first: (x: X) => Y): (f2: (y: Y) => Z) => (x: X) => Z {
return function (second: (y: Y) => Z): (x: X) => Z {
return function (x: X): Z {
return second(first(x));
};
}
}
function compose2<X, Y, Z>(second: (y: Y) => Z): (f2: (x: X) => Y) => (x: X) => Z {
return function (first: (x: X) => Y): (x: X) => Z {
return function (x: X): Z {
return second(first(x));
};
}
}
使用方法
function numToStr(n: number): string { return n.toString(); }
function strToLen(s: string): number { return s.length; }
// Inferred as (x: number) => unknown
// Should be (x: number) => number
const f1 = pipe(numToStr)(strToLen);
// Inferred as(x: unknown) => number
// Should be (x: number) => number
const f2 = compose(strToLen)(numToStr);
而不是硬编码每个函数的返回类型。允许打字稿推断它并确保不太早使用通用参数:
function pipe<X, Y>(first: (x: X) => Y) {
return function <Z>(second: (y: Y) => Z) {
return function (x: X) {
return second(first(x));
};
}
}
function compose<Y, Z>(second: (y: Y) => Z) {
return function <X>(first: (x: X) => Y) {
return function (x: X): Z {
return second(first(x));
};
}
}
function numToStr(n: number): string { return n.toString(); }
function strToLen(s: string): number { return s.length; }
const f1 = pipe(numToStr)(strToLen);
const f2 = compose(strToLen)(numToStr);