ClassDecorator with Angular (15) targeting ES2022

问题描述 投票:0回答:1

我们现在是 2023 年 3 月,我正在寻找一种方法让我的类装饰器以正确的方式工作,而不会收到来自 cli 的警告。

这是我的简单代码:

function MyDecorator(myConstructor: new (...args: any[]) => any): new (...args: any[]) => any {
  alert('MyDecorator EVALUATE'); // -------------> Alert A
  return class extends myConstructor {
    constructor(...args) {
      super(...args);
      alert('MyDecorator CONSTRUCTOR'); // ------------> Alert B
    }
  };
}

@MyDecorator
@Component({
  // ...
})
export class AppComponent() {
  // ...
} 

Angular 15 之前:

我的目标是 ES2021 或更低版本,这非常有效。我收到警报 A 和 B,cli 没有发出警告。

Angular 15:

我仍然以 ES2021 为目标,它仍在工作。我收到警报 A 和 B

但是 cli 警告我它覆盖了一些设置。

TypeScript compiler options "target" and "useDefineForClassFields" are set to "ES2022" and "false" respectively by the Angular CLI. To control ECMA version and features use the Browerslist configuration. For more information, see https://angular.io/guide/build#configuring-browser-compatibility

我尝试在

tsconfig.json

中设置这两个设置
    "target": "ES2022",
    "useDefineForClassFields": false,

然后我没有更多的 cli 警告但是我只收到警报 A 并且我的装饰器实现显然被忽略了(没有显示警报 B)。

看起来

"useDefineForClassFields": false
被忽略了(cf:https://github.com/angular/angular/issues/48276#issuecomment-1362787912

我的两个问题是:

  • 有没有办法让装饰器在 Angular 15/ES2022 中“本地”工作?
  • 如果没有,有没有办法正确设置
    useDefineForClassFields
    compilerOption以避免cli的警告?

在此先感谢您的帮助/解释...

angular angular-cli decorator tsconfig es2022
1个回答
0
投票

“有没有办法让装饰器在 Angular 15/ES2022 中“本地”工作? “

从 Angular 15 开始,似乎无意支持应用于角度组件的自定义装饰器:

https://github.com/angular/angular/issues/48276#issuecomment-1332611012

Angular 不支持在其组件类或其他装饰成员上自定义装饰器。根据装饰器的作用,它可能会或可能不会正常工作。

我们不支持它们,因为存在很大的概念不匹配——Angular 编译器试图根据它们的 Angular 注释静态转换类,但自定义装饰器试图在运行时任意更改该类的形状。


“如果没有,有没有办法正确设置 useDefineForClassFields compilerOption 以避免 cli 的警告?”

我相信您会收到此警告,因为它期望在定位

useDefineForClassFields
时将默认值用于
ES2022

https://angular.schule/blog/2022-11-use-define-for-class-fields

[当]TypeScript 的目标设置为 ES2022 时,此选项的默认值为 true

这面旗帜到底有什么作用?

这意味着将使用 JavaScript 的本机实现,并且属性的行为方式将与以前不同。根据设置,以下代码有两个不同的输出:

class User {
 age = this.currentYear - 1998;

 constructor(private currentYear: number) {
   // useDefineForClassFields: false --> Current age: 25
   // useDefineForClassFields: true --> Current age: NaN
   console.log('Current age:', this.age);
 }
}

const user = new User(2023);
© www.soinside.com 2019 - 2024. All rights reserved.