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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:55:11