! 非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 の行単位の例外を使います。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%