【问题标题】:Typescript property decorator weird behaviour打字稿属性装饰器奇怪的行为
【发布时间】:2022-12-31 08:36:11
【问题描述】:

我有一个简单的类

class Component {
  @id() instanceId: string;

  @id() secondaryId: string;

  log() {
    console.log(this.instanceId, this.secondaryId);
  }
}

和一个装饰师

const id = (): PropertyDecorator => {
  return (target, name) => {
    const descriptor = {
      get(this: any) {
        const propertyName = `__${String(name)}`;

        if (!this[propertyName]) {
          this[propertyName] = 'MY ID';
        }

        return this[propertyName];
      },
      enumerable: true,
      configurable: true
    };

    Object.defineProperty(target, name, descriptor);
  };
};

我的tsconfig.json 看起来像这样:

{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "alwaysStrict": true,
    "esModuleInterop": true,
    "declaration": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strictPropertyInitialization": false,
    "target": "ESNext",
    "module": "CommonJS",
    "moduleResolution": "node",
    "types": [
      "node"
    ]
  }
}

当我执行以下操作时:

const cmp = new Component();
cmp.log();

我希望 "MY ID", "MY ID" 将打印在控制台中,但我得到的是 undefined, undefined

此示例在 TS playground (link) 中按预期工作,但在本地甚至在 CodeSandbox (link) 上都不起作用。

怎么了?

【问题讨论】:

  • 您在本地使用的是什么版本的 Typescript?什么是转译器输出?

标签: javascript typescript typescript-decorator


【解决方案1】:

试试这个

const id = (): PropertyDecorator => {
  return (target:any, name) => {
    const propertyName = `__${String(name)}`;

    if (!target[propertyName]) {
      target[propertyName] = 'MY ID';
    }

    const descriptor = {
      value: target[propertyName],
      enumerable: true,
      configurable: true
    };

    Object.defineProperty(target, name, descriptor);
  };
};

playground link

更新

targetparam 指的是应用装饰器的对象。

nameparam 是应用装饰器的属性或方法的名称。

【讨论】:

  • 为什么? OP 显然想要定义一个 getter 属性。
  • 原来问题出在"target": "ESNext"。当我将其更改为 "target": "ES2021" 时,它就如我所料地工作了。很奇怪
  • @guesswhat 我想你得到了答案?
  • 好的,这实际上是因为useDefineForClassFields 字段而发生的。但是这个参数实际上做了什么?
  • @Bergi OP 说I expect that "MY ID", "MY ID" will be printed in the console, but I get undefined, undefined instead.
猜你喜欢
  • 2021-01-26
  • 2021-07-11
  • 2021-12-01
  • 2018-11-15
  • 2021-10-28
  • 2021-12-06
  • 2018-02-23
  • 2018-06-21
  • 2019-07-29
相关资源
最近更新 更多