【发布时间】:2023-01-07 21:35:01
【问题描述】:
我正在尝试为所有第三方 API 接口和 SDK 编写一个包装器,以标准化但可自定义的方式记录请求。我想这样做的方法是将第三方 API(通常通过 new API() 调用实例化)传递到包装类 (APIClient)。该客户端接收到一个对象,该对象具有映射到日志记录功能的第三方 API 上的某些方法(例如,我可以说我可以指定何时需要清理 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>'.
(第二个不那么令人困惑,我知道 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`
}
};
}
}
【问题讨论】:
标签: javascript typescript class typescript-generics