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

TypeScript中使用Proxy对象时出现str.replace is not a function错误

问题原因

这个错误的核心是**console.log打印Proxy对象时会自动读取大量内部属性**,而你的Proxy陷阱逻辑没过滤这些特殊属性,导致触发了get方法。但你的Entry.get是异步方法,默认返回Promise,后续Object.assign(this, Promise)的过程中,控制台格式化输出时的内部字符串处理拿到了非字符串值,从而抛出str.replace is not a function错误。

具体细节:

  • console.log打印Proxy时,会尝试访问toString、Symbol.toStringTag、Symbol.iterator这类内部属性,这些属性不在你的实例上,所以进入了cache miss分支。
  • 异步的get方法返回Promise,Object.assign(this, Promise)会把Promise的内部方法(比如then、catch)挂到实例上,控制台格式化这些内容时,误将非字符串值传入了需要调用replace的逻辑,最终报错。
解决方法

1. 过滤特殊属性,避免触发get逻辑

在Proxy的get陷阱里,先判断属性是否为Symbol或Object原型上的方法,直接返回默认值,不触发自定义get逻辑:

abstract class Lazy<T> {
  constructor(obj: Partial<T>) {
    Object.assign(this, obj);
    return new Proxy(this, {
      get: (t, p) => {
        // 过滤Symbol属性和Object原型上的方法,直接返回默认值
        if (typeof p === 'symbol' || p in Object.prototype) {
          return Reflect.get(t, p);
        }
        // cache hit
        if (p in t) return t[p as keyof T];
        // cache miss, 处理get的返回值
        const result = this.get(p);
        // 处理异步返回的Promise
        if (result instanceof Promise) {
          result.then(data => Object.assign(t, data));
          // 暂时返回undefined,或根据需求返回占位值
          return undefined;
        }
        return Object.assign(t, result);
      },
    });
  }

  protected abstract get(prop: any): any;
}

2. 修正Entry.get的返回逻辑

确保异步get方法返回包含目标属性的对象,而非空值:

class Entry extends Lazy<Entry> {
  protected async get(prop: keyof Entry) {
    // 模拟异步获取数据(比如API请求)
    await new Promise(resolve => setTimeout(resolve, 100));
    // 返回对应属性的对象
    if (prop === 'id') {
      return { id: 123 };
    }
    return {};
  }
}

3. 调试时可选:避免直接打印Proxy对象

如果只是调试需要,可以打印实例的原始副本,绕开Proxy的拦截:

const entry = new Entry({});
console.log(Object.assign({}, entry));

内容的提问来源于stack exchange,提问作者Arda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:33:10