🟨
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
用途に応じて使い分けてください!
Discussion