You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 04:40:53