使用TypeScript的高阶函数参数

8qgya5xd  于 2023-05-19  发布在  TypeScript
关注(0)|答案(2)|浏览(151)

我正在尝试创建一个高阶函数(不确定是否有更好的名称),它可以通用地接受带有任何参数的任何函数,它返回一个新函数,该函数具有相同的输入参数。
例如,如果我有一个函数:

function func1(arg1: number, arg2: string) {
  return `${arg1}${arg2}`
}

我希望能够将它传递到一个函数中,如下所示:

const func2 = hof(func1);
// type of func2 should be: (arg1: number, arg2: string, arg3: number) => string
func2(1, "test", 2);

我试着写hoc像这样:

function hof<P, T>(fn: (...params: P) => T): T {
  return (...params, arg: number) => {
    // ... do some extra stuff using the extra `arg`
    return fn(...params);
  }
}

这看起来不太对我不认为我真的想把params扩展到数组中,因为我希望我生成的函数像在给定函数中一样接受原始参数(而不是作为数组)。
这是否可能使Typescript给予我一个智能的响应/类型?

bf1o4zei

bf1o4zei1#

这是一个相当混乱的这样做,但是的,可能类似于:

function hof<A extends ReadonlyArray<unknown>, R>(fn: (...params: A) => R) {
    return (...args: [...params: A, arg: number]) => {
        const [arg, ...params] = [args[args.length - 1], ...args.slice(0, -1)] as [arg: number, ...params: A];
        return fn(...params);
    };
}

它看起来很不稳定,因为rest参数不能放在第一位。所以我不得不把类型改为[...params: A, arg: number],然后在主体中解构它。
Playground

9gm1akwq

9gm1akwq2#

function hof<T extends (...args: [number, string, ...any[]]) => any>(
  fn: T
): (...args: Parameters<T>) => ReturnType<T> {
  return (...args: Parameters<T>): ReturnType<T> => {
    const [arg0, arg1] = args;

    return fn(...([arg0, arg1, ...args] as const));
  };
}

希望这个解决方案能有所帮助

相关问题