/** ***************************************** * Created by edonet@163.com * Created on 2018-04-09 22:26:49 ***************************************** */ 'use strict'; /** ***************************************** * 加载依赖 ***************************************** */ import { U, F } from './d'; /** ***************************************** * 参数 ***************************************** */ type Args = ( P extends T ? T : T extends [] ? [] : T extends [U] ? [P[0]] : T extends [...rest: infer W, last: U] ? [...Args, P[W['length']]] : P ); /** ***************************************** * 处理函数 ***************************************** */ type Handler = (...args: T) => P; /** ***************************************** * 柯里化 ***************************************** */ type Curry = ( T extends [] ? () => P : T extends [infer V] ? (argv: V) => P : Curried ); /** ***************************************** * 柯里化函数 ***************************************** */ interface Curried { (...args: Args): ( T extends [...args: I, ...rest: infer R] ? Curry : never ); } /** ***************************************** * 柯里化 ***************************************** */ export function curry(handler: Handler): Curry { // 校验参数 if (typeof handler !== 'function') { throw new Error('expect handler to be a function!'); } // 获取参数数量 const arity = handler.length; // 参数少于2个 if (arity < 2) { return handler as Curry; } // 生成柯里化函数 return makeCurry(handler as F, arity, []) as Curry; } /** ***************************************** * 创建柯里化函数 ***************************************** */ function makeCurry(handler: F, arity: number, cached: unknown[]) { return function curried(this: unknown, ...args: unknown[]) { // 未传参数 if (!args.length) { return curried; } // 合并参数 args = cached.concat(args); // 判断参数是否足够 if (args.length >= arity) { return handler.apply(this, args); } // 生成新的函数 return makeCurry(handler, arity, args); }; }