! 非nullアサーション
最終更新:2026-10-22
! 非nullアサーション
非nullアサーション(後置 !)はコンパイラに「この値は今は間違いなく null/undefined ではない」と伝え、T | null | undefined を T に潰します。実行時のチェックは一切行いません。値が本当に空なら、エラーは後続のアクセス箇所で初めて爆発します。そのため「本当に空値を排除し終えた」場面でだけ使いましょう。
| グループ | ナローイングとアサーション |
|---|---|
| 種類 | 演算子 |
| strict モード | 不要 |
ℹ️ 説明 エディタは TypeScript を JavaScript にトランスパイルして実行します(型チェックなし)。型チェック結果は各サンプルの出力を参照してください。
📝 構文
const el = document.getElementById("root")!; // HTMLElement | null ではなく HTMLElement
const user = map.get("alice")!; // User | undefined ではなく User
console.log(user.name);
⚙️ パラメータ
| ! | 式の後に置く後置演算子です。型から null と undefined を取り除くだけで、実行時コードを一切生成しません |
|---|
戻り値:実行時の効果はありません。トランスパイル後は ! が完全に消え、コンパイル時には型から null/undefined のメンバーを取り除くだけです。
▶ サンプル
下のコードを編集して「試す」を押すと、トランスパイル実行結果を確認できます:
出力:
100
no record
(トランスパイル後の実行出力。aliceScore + 9 が型チェックを通るのは ! が型を絞り込んだからです。bob に対しても scores.get("bob")! + 1 と書くと、コンパイルは通るものの実行時には NaN になります。! は何も検査しません)
💡 ポイント
⚠️ 注意 ! はコンパイラへの口頭の保証であり、実行時の検証はゼロです。判断を誤ってもすぐにはエラーにならず、後のどこかの .プロパティ アクセスで TypeError が投げられ、特定が困難です。if (x) や ?? で対処できる場面ではそちらを優先しましょう。
ℹ️ 説明 ! は null/undefined を取り除くだけで、他のナローイングはしません。string | number | null に x! を書いて得られるのは string | number で、string ではありません。
💡 ヒント 広く認められている合理的な場面は次のとおりです。getElementById の後に要素の存在が確定している場合、Map.set の後に同じキーを get する場合、テストコードでフィクスチャを組む場合。業務の主要フローに連なる ! の塊はコードの悪臭です。
🏷️ 関連ナローイングとアサーション
💡 関連ケース
ケースは今後追加予定です。
📚 関連チュートリアル
❓ よくある質問
Q ! と ?.(オプショナルチェーン)の違いは何ですか?
A 方向が正反対です。! は「間違いなく非null」と主張し、空でもそのまま爆発します。?. は「空かもしれない」ことを認め、空なら undefined を返して短絡します。防御的なコードには ?. を、確実に非nullなときだけ ! を使いましょう。
Q strictNullChecks を切っていれば ! は必要ですか?
A 必要ありません。null/undefined はどの型にも代入可能になり、! にはやることがありません。これこそ strictNullChecks を常に有効にすべき理由の1つです。切っていると ! は純粋なノイズになり、空値のバグはすべて実行時に回されます。
Q 多くのチームが ESLint で ! を禁止しているのはなぜですか?
A ! は空値のリスクを黙って吸い込み、リファクタリングで前提が崩れても if チェックのようなコンパイルエラーを出さないからです。禁止すればガードや ?? のフォールバックが強制され、長期的に安全です。少数の確信できる場面には eslint-disable の行単位の例外を使います。