如何用Proxy包装TypeScript类并解决类型索引错误?
TypeScript中用Proxy包装API类实例并处理类型问题
你遇到的类型错误是因为TypeScript无法确认prop(类型为string | symbol)是API或其子类的有效属性键,直接用target[prop]会触发类型检查报错。这个需求完全可以在TypeScript中实现,只需要通过类型守卫缩小prop的类型范围,让TypeScript识别它是目标对象的合法方法键即可。
修改后的完整代码
class API { sayHello(name: string) { console.log("hello " + name); return name; } } // 类型守卫:判断当前属性是否为实例的方法 function isInstanceMethod<T>(target: T, prop: PropertyKey): prop is keyof T { return typeof target[prop as keyof T] === "function"; } export default <T extends API>(api: T) => { return new Proxy(api, { get(target, prop) { // 处理非方法属性,直接返回原属性值 if (!isInstanceMethod(target, prop)) { return target[prop as keyof T]; } // 包装方法,添加日志、错误处理逻辑 const originalMethod = target[prop] as (...args: any[]) => Promise<any> | any; return async (...args: Parameters<typeof originalMethod>) => { try { console.log(`调用方法:${String(prop)},参数:`, args); const res = await originalMethod(...args); console.log(`方法${String(prop)}调用成功,返回值:`, res); return res; } catch (e) { console.error(`方法${String(prop)}调用失败,错误:`, e); // 自定义错误处理逻辑,比如抛出包装后的错误 throw new Error(`API调用失败:${(e as Error).message}`); } }; }, }); };
关键修改说明
- 类型守卫函数:
isInstanceMethod通过检查属性值是否为函数,让TypeScript确认prop是目标对象T的合法键,消除索引类型错误。 - 非方法属性处理:用
prop as keyof T做类型断言,告诉TypeScript当前属性是目标对象的有效属性,直接返回原值。 - 方法包装:先将原方法断言为通用函数类型,再用
Parameters<typeof originalMethod>自动推导方法的参数类型,保证调用时的类型安全。 - 日志与错误处理:在包装函数中添加了调用日志、成功日志和错误捕获逻辑,满足你需求中的日志记录和自定义错误处理。
使用示例
const api = new API(); const wrappedApi = wrapAPI(api); wrappedApi.sayHello("Alice"); // 输出: // 调用方法:sayHello,参数: ["Alice"] // hello Alice // 方法sayHello调用成功,返回值: Alice
内容的提问来源于stack exchange,提问作者nickhealy
相关产品推荐
相关产品推荐

