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

发布于 2022-09-13 01:16:12 字数 913 浏览 20 评论 0

《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 );
            }
        };
    })( [] );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

何处潇湘 2022-09-20 01:16:12

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;
}
挽清梦 2022-09-20 01:16:12

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

所以你可以直接

 let args = prevArgs.concat(nextArg)

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文