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

ES5与experimentalDecorators配置下,Accessor Decorators descriptor为undefined

TypeScript访问器装饰器descriptor始终为undefined的解决办法

问题场景

你定义了Point类和configurable装饰器,tsconfig里target设为ES5、开启了experimentalDecorators,但运行时装饰器中的descriptor参数一直是undefined,代码和配置如下:

代码示例

class Point {
  private _x: number;
  constructor(x: number, y: number) {
    this._x = x;
  }
 
  @configurable(false)
  get x() {
    return this._x;
  } 
}

function configurable(value: boolean) {
  return function (target: any, propertyKey: string, descriptor?: PropertyDescriptor) {
    console.log("called.....", descriptor);
    if (descriptor) {
      console.log("called.....", descriptor);
      descriptor.configurable = value;
    }
  };
}

tsconfig配置

{
  "compilerOptions": {
    "target": "ES5",
    "experimentalDecorators": true
  }
}

问题原因

当TypeScript编译目标设为ES5时,类的访问器(getter/setter)会被编译成基于Object.defineProperty的ES5兼容代码,但实验性装饰器在ES5模式下,不会为访问器装饰器传入descriptor参数。这是因为ES5本身没有原生类语法,TypeScript的模拟实现无法在装饰器阶段直接提供完整的PropertyDescriptor。

解决方案

方案1:升级编译目标到ES6+

修改tsconfig的target为ES2015(即ES6)或更高版本,此时TypeScript会使用原生类语法编译,访问器装饰器就能正确获取到descriptor:

{
  "compilerOptions": {
    "target": "ES2015",
    "experimentalDecorators": true
  }
}

方案2:手动获取并修改descriptor(兼容ES5)

如果必须保持ES5编译目标,可以在装饰器中手动从类原型上获取访问器的描述符,修改后重新定义:

function configurable(value: boolean) {
  return function (target: any, propertyKey: string) {
    // 从类原型上获取访问器的descriptor
    const descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
    if (descriptor) {
      descriptor.configurable = value;
      // 重新定义访问器
      Object.defineProperty(target, propertyKey, descriptor);
    }
  };
}

注:这里的target指向类的原型,你的get x是定义在类原型上的访问器,因此该方法可以正常生效。

验证

修改后运行代码,装饰器中的descriptor将不再是undefined,configurable属性会被正确设置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:05:19