如何键入通用函数参数以将回调样式函数包装成更 Promise 样式?

How to type Generic Function Parameters for wrapping a callback style function into a more Promise style?

我正在尝试创建一个泛型来处理将回调转换为同步式函数调用。

例如。 f(err: Error, response: ResponseT):void 应该变成 f(): ResponseT

我怎样才能做到这一点?

我有一个名为 wrap() 的函数,它已经这样做了。我如何正确声明它以保留类型?

尝试类似

function wrapAsync<A extends any[], E, R>(f: (...args: A, err: E, response: R) => void): R

但这并不能清楚地工作,因为 REST args 必须在任何其他参数之后。

可以,但有点棘手

  1. 获取最后一个参数的编号。最棘手的部分,因为 TS 不允许对类型进行算术运算。所以我们将函数转换为具有特定第一个参数的函数。那么...args变成长度减1的数组。然后我们推断...args数组的长度。

    type GetLastArgNum<F extends ((...args: any[]) => any)> = 
      F extends ((p1: any, ...args: infer R) => any) ? 
      R extends { length: infer L } ? L : never : never;
    
  2. 获取最后一个参数的类型。

    type GetLastArgType<F extends ((...args: any[]) => any)> = Parameters<F>[GetLastArgNum<F>]
    
  3. 最后转换成想要的函数类型

    type TransformFunction<F extends ((...args: any[]) => any)> = (() => GetLastArgType<F>)
    

并申请你的任务。如果我理解正确,你需要 wrapAsync 函数接受回调函数和 return 函数,它没有任何参数但 returns 最后一个参数类型的值。它看起来像

function wrapAsync<F extends ((...args: any[]) => any)> (f: F): (() => GetLastArgType<F>)

TS Playground