ClassDecorator с Angular (15) для ES2022
Сейчас март 2023 года, и я ищу способ заставить декораторы моих классов работать правильно, без предупреждения из командной строки.
Вот мой простой код:
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, но интерфейс не выдал никаких предупреждений.
С Угловым 15:
Я все еще ориентировался на ES2021, и он все еще работал. Я получил оповещения A и B
НО интерфейс предупредил меня, что он переопределил некоторые настройки.
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
игнорируется (см.: https://github.com/angular/angular/issues/48276#issuecomment-1362787912)
Ну, мои 2 вопроса:
- Есть ли способ заставить декораторы работать «исходно» в Angular 15/ES2022?
- если нет, есть ли способ правильно настроить
useDefineForClassFields
compilerOption, чтобы избежать предупреждения cli?
Заранее спасибо за любую помощь/объяснения...
1 ответ
«Есть ли способ заставить декораторы работать «изначально» в Angular 15/ES2022?»
Похоже, что поддержка пользовательских декораторов, применяемых к компонентам Angular, начиная с 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);