javascript 将 Package 器写入TS中的第三方类方法

rvpgvaaj  于 2023-01-07  发布在  Java
关注(0)|答案(1)|浏览(152)

我正在尝试为我所有的第三方API接口和SDK编写一个 Package 器,但可定制的方式。我想这样做的方式是通过第三方API(通常用new API()调用来初始化)到 Package 类中该客户端接收具有Map到日志记录函数的第三方API上的某些方法的对象(这样我就可以说我可以指定它什么时候需要santize PII,例如)它迭代这个对象,并在自己的this上重定义在第三方API上定义的方法,在调用第三方方法之后调用日志函数。这样,API可以具有与第三方API相同的接口,并具有自定义行为的优点。
当然,我已经为这上面的打字工作挣扎了很长时间,感觉我可能已经接近让它工作了,但是我还不能完全让它过线。我被TS文档中关于“Mixins”的部分所鼓舞,但是我不确定这是不是正确的方法。
我得到一些真正令人困惑的错误:
Type 'Function' provides no match for the signature '(...args: any): any'.
No index signature with a parameter of type 'string' was found on type 'ApiClient<T>'.
(The第二个不那么令人困惑,我知道Object.entries将键值对作为字符串和值,但我被困在做什么上了)
有人知道这里可能出了什么问题吗?我该怎么解决?谢谢。

type Constructor = new (...args: any[]) => {};
type Method<T, K extends keyof T> = T[K] extends Function ? T[K] : never;

class ApiClient<T extends Constructor> {
  _api: T;

  constructor(api: T, logConfig: Record<keyof T, () => void>) {
    this._api = api;

    for (const [method, fn] of Object.entries(logConfig)) {
      this[method] = this.createWrappedMethod(method, fn)
     }
  }

  createWrappedMethod<
    N extends keyof InstanceType<T>,
    M extends Method<InstanceType<T>, N>,
  >(name: N, logFn: () => void) {
    return async (...args: Parameters<M>) => {
      try {
        const res = await this._api[name](...args);
        // do logging
      } catch {
        // handle error`
      }
    };
  }
}
bd1hkmkf

bd1hkmkf1#

我不知道如何用您当前的方法解决类型问题,但是,看起来您正在做的事情与Proxy对象的设计目的非常相似。
简而言之,Proxy对象允许您重新定义对象上的某些操作,如属性访问,从而允许您 Package 和覆盖函数以插入日志记录和卫生。
例如,下面是一个 Package 在Proxy中的对象,它只是将方法调用的结果打印到控制台:

const api = new API();

const proxy = new Proxy(api, {
    get(target, prop) {
        if (typeof target[prop] !== "function") {
            return target[prop];
        }
        return async (...args) => {
            const res = await target[prop](...args);
            console.log(res)
            // do more stuff...
            return res;
        };
    },
});

这也可以自动与TypeScript一起使用;编译器会将代理对象的类型识别为原始对象的类型。换句话说,在TypeScript中,Proxy(new API(), {...})仍然是API

相关问题