我可以为具有一定数量参数的函数创建一个通用的currying函数。 IE)
function curry2<T1,T2,R>(func:(arg1:T1, arg2:T2) => R, param2: T2):(arg:T1) => R{
return (param1:T1) => func(param1, param2);
};
但是,我找不到(类型安全)方法来为具有任何个参数的函数实现通用curry函数。在另一种语言中,我将所有我的currying函数(即:curry1,curry2,curry3等)命名为相同的东西(curry),然后让函数重载执行正确执行curry的工作。但是,typescript不允许像这样的函数重载。
在任何地方写curry2 / curry1 / curry3而不是咖喱的单一统一界面并不麻烦,但如果有办法做到这一点我会很高兴知道如何!
答案 0 :(得分:1)
在任何地方写curry2 / curry1 / curry3而不是单一的咖喱统一界面并不麻烦,
您可以进行重载(文档https://basarat.gitbooks.io/typescript/content/docs/types/functions.html)
让你入门的东西:
function curry<T1,T2,R>(func:(arg1:T1, arg2:T2) => R, param2: T2):(arg:T1) => R;
function curry<T1,T2,T3,R>(func:(arg1:T1, arg2:T2, arg3: T3) => R, param2: T2):(arg:T1) => R;
function curry(){
// Implement
return undefined;
};
答案 1 :(得分:0)
basarat的例子相当不错,但第二次重载似乎不正确。 这是我在为咖喱函数编写类型签名时想出的:
interface curry {
<T1, T2, R>(func: (p1: T1, p2: T2) => R): (p: T1) => (p: T2) => R;
<T1, T2, T3, R>(func: (p1: T1, p2: T2, p3: T3) => R): (p: T1) => (p: T2) => (p: T3) => R;
<T1, T2, T3, T4, R>(func: (p1: T1, p2: T2, p3: T3, p4: T4) => R): (p: T1) => (p: T2) => (p: T3) => (p: T4) => R;
<T1, T2, T3, T4, T5, R>(func: (p1: T1, p2: T2, p3: T3, p4: T4, p5: T5) => R): (p: T1) => (p: T2) => (p: T3) => (p: T4) => (p: T5) => R;
}
当然,您可以使用更多参数重复它,直到达到安全深度:)
// the actual curry function implementation ommited
var makeCurry: curry = <any> null;
// example function that we would like to curry, with two parameters
var getInfo = (age: number, name: string) => {
return `${name} is ${age} years old`;
}
// the previous function curried
var getInfoCurried = makeCurry<number, string, string>(getInfo);
var info = getInfoCurried(26)('Gergo');
答案 2 :(得分:-1)
curry.ts:
export interface curry1<T1, R> {
(): curry1<T1, R>;
(t1: T1): R;
}
export interface curry2<T1, T2, R> {
(): curry2<T1, T2, R>;
(t1: T1): curry1<T2, R>;
(t1: T1, t2: T2): R;
}
export interface curry3<T1, T2, T3, R> {
(): curry3<T1, T2, T3, R>;
(t1: T1): curry2<T2, T3, R>;
(t1: T1, t2: T2): curry1<T3, R>;
(t1: T1, t2: T2, t3: T3): R;
}
// etc...
export function curry<T1, R>(fn: (t1: T1) => R): curry1<T1, R>;
export function curry<T1, T2, R>(fn: (t1: T1, t2: T2) => R): curry2<T1, T2, R>;
export function curry<T1, T2, T3, R>(fn: (t1: T1, t2: T2, t3: T3) => R): curry3<T1, T2, T3, R>;
// etc...
export function curry(fn) {
const f = (fn, length, arr) =>
(...args) =>
args.length < length ?
f(fn, length - args.length, arr.concat(args)) :
fn(...arr.concat(args));
return f(fn, fn.length, []);
}
tsc -v = 2.2.2