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

TypeScript中能否实现自实例化的getter属性?

在TypeScript中实现延迟加载且自动替换为实例属性的Getter

当然可以实现,下面是满足你需求的强类型解决方案——核心思路是第一次调用getter时创建实例,随后将该getter替换为普通实例属性,避免后续访问时重复执行初始化逻辑:

基础实现版本

interface PropInstance {
  data: string;
}

class MetadataHolder {
  get prop(): PropInstance {
    // 移除当前的getter定义,替换为实例属性
    Object.defineProperty(this, 'prop', {
      value: { data: 'Here is the data' },
      writable: true,
      enumerable: true,
      configurable: true
    });
    console.log('Creating instance');
    return this.prop;
  }
}

// 测试代码
const obj = new MetadataHolder();
console.log(obj.prop.data); // 输出 "Creating instance" 和 "Here is the data"
console.log(obj.prop.data); // 直接输出 "Here is the data",不再触发初始化逻辑

多属性场景的优化方案(装饰器封装)

如果你的类有大量这类元数据属性,用装饰器封装可以避免重复代码,同时保持强类型:

// 定义延迟加载属性的装饰器
function lazyProperty<T, K extends keyof T>(
  target: T,
  propertyKey: K,
  descriptor: PropertyDescriptor
) {
  const originalGet = descriptor.get!;
  descriptor.get = function() {
    const value = originalGet.call(this);
    // 将getter替换为普通数据属性
    Object.defineProperty(this, propertyKey, {
      value,
      writable: true,
      enumerable: true
    });
    return value;
  };
  descriptor.configurable = true;
}

// 示例实例类型
interface PropInstance {
  data: string;
}

interface AnotherMetaInstance {
  value: number;
}

class MetadataHolder {
  @lazyProperty
  get prop(): PropInstance {
    console.log('Creating prop instance');
    return { data: 'Here is the data' };
  }

  @lazyProperty
  get anotherMeta(): AnotherMetaInstance {
    console.log('Creating anotherMeta instance');
    return { value: 42 };
  }
}

// 测试代码
const obj = new MetadataHolder();
console.log(obj.prop.data); // 触发初始化,输出日志和数据
console.log(obj.prop.data); // 直接访问属性,无日志
console.log(obj.anotherMeta.value); // 触发初始化,输出日志和值
console.log(obj.anotherMeta.value); // 直接访问属性,无日志

原理说明

  • 第一次访问getter时,执行初始化逻辑创建实例;
  • 随后通过Object.defineProperty将该属性重新定义为普通数据属性,覆盖原有的getter;
  • 后续访问时直接读取属性值,完全跳过getter的检查和初始化逻辑,兼顾了延迟加载和性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:35:28