《JavaScript 轻量级函数式编程》 中的柯里化函数怎么转成TypeScript版

WingDust
  • 177

《JavaScript 轻量级函数式编程》中的柯里化函数

function curry(fn,arity = fn.length) {
    return (function nextCurried(prevArgs){
        return function curried(nextArg){
            var args = prevArgs.concat( [nextArg] );

            if (args.length >= arity) {
                return fn( ...args );
            }
            else {
                return nextCurried( args );
            }
        };
    })( [] );
}

转成TypeScript版

  function curry(fn:Function,arity = fn.length) {
    return (function nextCurried(prevArgs){
        return function curried(nextArg: any){
            var args = prevArgs.concat( [nextArg] );//这里 Error 应该写成什么样

            if (args.length >= arity) {
                return fn( ...args );
            }
            else {
                return nextCurried( args );
            }
        };
    })( [] );
}
回复
阅读 1k
2 个回答

This might be a more complicated solution. but,
it works

type Func<T, U> = T extends any[] ? (...args: T) => U : (arg: T) => U;
type AnyFunc = Func<any[], any>;
type Argc<T extends AnyFunc> = T extends (...args: infer R) => any
  ? R["length"]
  : never;
type isTuple<T extends { length: number }> = T["length"] extends number
  ? number extends T["length"]
    ? false
    : true
  : true;
export type Curry<T extends AnyFunc> = Argc<T> extends 1 ? T : Funcs<T>;
type Funcs<T extends AnyFunc> = T extends (
  ...args: [infer F, ...infer R]
) => infer U
  ? (arg: F) => Curry<Func<R, U>>
  : never;
type Args<T extends AnyFunc> = T extends (...args: infer U) => any ? U : never;

export function curry<T extends AnyFunc>(
  fn: T,
  context: any = null
): isTuple<Args<T>> extends true ? Curry<T> : never {
  const curried: any = function (this: any, ...t: any[]) {
    if (t.length >= fn.length) {
      return context ? fn.call(context, ...t) : fn(...t);
    }
    return curried.bind(null, ...t);
  };
  return curried;
}

concat传数组传元素都可以,反正是拼接。逻辑上没有问题。只不过你的ts版本可能告诉你concat返回一个never[],这个应该是已经修正成T[]了。

所以你可以直接

 let args = prevArgs.concat(nextArg)

或者按照楼上去严格限制函数的参数

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏