Angular 17对话框组件构造器中@Inject装饰器报错问题
Angular 17 + Material 17 对话框组件构造器注入报错解决
问题重现
在Angular 17.0.7 + Material 17.0.4 + TypeScript 5.2.2环境下创建独立对话框组件时,在构造函数参数中使用@Inject(MAT_DIALOG_DATA)装饰器,出现Decorators are not valid here.ts(1206)错误。
组件代码(报错版本):
import { Component, Inject } from '@angular/core'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; @Component({ selector: 'app-reject', standalone: true, imports: [MaterialModule], templateUrl: './reject.component.html', styleUrl: './reject.component.scss', }) export class RejectComponent { constructor( @Inject(MAT_DIALOG_DATA) public data: any, // 此处报错:Decorators are not valid here.ts(1206) public dialogRef: MatDialogRef<RejectComponent>, ) {} public editorConfig = EDITOR_CONFIG; commentFormControl = new FormControl(''); onCancel(): void { this.dialogRef.close(); } }
tsconfig.json配置:
{ "compileOnSave": false, "compilerOptions": { "baseUrl": ".", "outDir": "./dist/out-tsc", "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "sourceMap": true, "declaration": false, "downlevelIteration": true, "experimentalDecorators": true, "moduleResolution": "node", "importHelpers": true, "target": "ES2022", "module": "ES2022", "useDefineForClassFields": false, "lib": ["ES2022", "dom"], "paths": {}, "rootDir": "." }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true }, "exclude": ["node_modules", "tmp"] }
错误原因
Angular 17默认启用ES标准装饰器,而TypeScript 5.x对ES标准装饰器的参数装饰器支持有限,@Inject作为参数装饰器无法在构造函数参数上直接使用(旧的实验性装饰器模式允许,但新标准不兼容)。
解决方案
方案1:使用inject()函数替代构造器参数装饰器(推荐)
Angular 14+推荐使用inject()函数进行依赖注入,尤其适合独立组件,无需依赖构造器参数装饰器:
修改后的组件代码:
import { Component, inject } from '@angular/core'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { FormControl } from '@angular/forms'; // 补充导入FormControl @Component({ selector: 'app-reject', standalone: true, imports: [MaterialModule], templateUrl: './reject.component.html', styleUrl: './reject.component.scss', }) export class RejectComponent { // 使用inject()获取对话框引用和数据 private dialogRef = inject(MatDialogRef<RejectComponent>); public data = inject(MAT_DIALOG_DATA); public editorConfig = EDITOR_CONFIG; commentFormControl = new FormControl(''); onCancel(): void { this.dialogRef.close(); } }
方案2:回退到实验性装饰器模式(不推荐)
如果需要继续使用参数装饰器,可修改tsconfig.json配置,强制使用旧的实验性装饰器:
在compilerOptions中添加以下配置:
"emitDecoratorMetadata": true, "decorateWhenPossible": false
修改后的tsconfig.json关键部分:
"compilerOptions": { // ...其他原有配置 "experimentalDecorators": true, "emitDecoratorMetadata": true, "decorateWhenPossible": false }
注意:此方案不符合ES标准装饰器的发展趋势,官方不推荐长期使用。
内容的提问来源于stack exchange,提问作者Daneshwaran M
相关产品推荐
相关产品推荐

