@Input 屬性的非空斷言與必要標記

在傳統 @Input() 裝飾器中

非空斷言操作符 (!)

@Input() avatar!: string;

! 是 TypeScript 的非空斷言操作符,它告訴 TypeScript 編譯器此屬性雖然未在構造函數中初始化,但會在實際使用前被賦值。這樣可以停用 TypeScript 的嚴格初始化檢查,避免編譯時錯誤。

required 標記

@Input({ required: true }) avatar!: string;

required: true 是 Angular 提供的執行時檢查機制:

  • 確保父組件一定要提供此屬性值

  • 若父組件模板未提供該屬性,Angular 會在編譯模板時產生錯誤

  • 這是在應用執行前的 Angular 模板編譯階段進行檢查

最佳實踐

// ✅ 推薦寫法:同時使用 required 和非空斷言
@Input({ required: true }) avatar!: string;

// ⚠️ 只使用非空斷言:缺少執行時檢查
@Input() avatar!: string;

// ⚠️ 只使用 required:仍需處理 TypeScript 初始化檢查
@Input({ required: true }) avatar: string;

!required 各自處理不同層面的檢查:

  • !:處理 TypeScript 的編譯時類型檢查

  • required:處理 Angular 的模板編譯檢查

在 Angular 17+ 的新 input() 函數中

基本用法

// 定義必要的 input
avatar = input.required<string>();

// 使用時需要加上括號
ngOnInit() {
  console.log(this.avatar()); // 正確用法
  // console.log(this.avatar); // ❌ 錯誤用法
}

新語法的優點:

  • 不需要使用非空斷言操作符

  • required 是函數而非配置對象

  • 類型為 InputSignal<string>,是一個信號型數據

  • 自動處理類型安全問題

可選 input

// 定義可選的 input
description = input<string>(); // 沒有 .required

預設值

// 定義帶預設值的 input
count = input<number>(0); // 預設值為 0

新舊語法對比

特性
傳統語法
新語法

必要屬性

@Input({ required: true }) prop!: string;

prop = input.required<string>();

可選屬性

@Input() prop?: string;

prop = input<string>();

預設值

@Input() prop: string = 'default';

prop = input<string>('default');

使用方式

this.prop

this.prop()

類型

原始類型 (如 string)

InputSignal<T>

Last updated