341 文字
2 分
TypeScriptの「?」と「!」の違い

TypeScriptにおける

foo?: number

foo!: number

の違いを分かりやすく解説します。


foo?: number の意味#

  • 「foo」はオプショナル(省略可能)なプロパティです。
  • 型は number または undefined になります。
  • オブジェクトを生成する際、fooを指定してもしなくてもOKです。

例:

type Example = {
foo?: number;
};
const a: Example = {}; // OK(fooなし)
const b: Example = { foo: 42 }; // OK

foo!: number の意味#

  • 「foo」は必須プロパティですが、**「!」は definite assignment assertion(確定代入アサーション)**です。
  • TypeScriptに「このプロパティは必ず初期化される」と伝えるための記法です。
  • コンストラクタや後から必ず値を代入する場合など、TypeScriptの「初期化されていないかも」というエラーを抑制します。
  • 型は number のみ(undefinedは許されません)

例:

class Example {
foo!: number; // ここで初期化していなくてもエラーにならない
constructor() {
this.foo = 42; // 後で必ず代入する
}
}

まとめ表#

記法意味初期化必須undefined許容
foo?: numberオプショナルプロパティ(省略可)number | undefined不要
foo!: number必須プロパティ(後で必ず初期化する宣言)number必要×

どちらを使う?#

  • 「fooがなくてもいい」場合foo?: number
  • 「fooは必ず存在するが、初期化タイミングは後」foo!: number

用途に応じて使い分けてください!