TypeScriptの世界へようこそ!
型安全という「頼もしいガードマン」が守ってくれる快適な開発に慣れてくると、時々こんなイライラを感じたことはありませんか?
「自分はこのデータが絶対にそこにあるって分かってるのに、TypeScriptのコンパイラが『もしかしたらnullかもしれないよ!』って怒ってくる……!」
そんなときに出会うのが、今回お話しする非nullアサーション演算子(`!`)です。
コードの最後に「!」をつけるだけで、TypeScriptの小言をピタッと止められる魔法のような記号なのですが……実はこれ、現場のエンジニアの間では「劇薬」として扱われています。
今日は、この「!」の正体と、可愛く見えて実はちょっと危ないその性格について、お買い物の例えを交えながら優しく紐解いていきましょう。大丈夫、つまずきやすいポイントは私がしっかりサポートしますよ!
—
1. 「!」ってどんなもの? 身近なたとえ話でお話します
まずイメージしてみてください。
あなたは今、スーパーにお買い物に来ています。お目当ての「特売のプリン」を買うために、エコバッグ(変数)をレジ袋から取り出しました。
あなたの中では「今、手元にエコバッグがあるから、この中にプリンを入れられる」と100%分かっていますよね。
しかし、TypeScriptくん(コンパイラ)は、ちょっと心配性で慎重すぎるアシスタントです。
「ねえ、本当にエコバッグある? もしかしたら家に忘れてきて、空っぽの手かもしれないよ? そんな状態で『プリンを入れて!』って言われても、エコバッグが`null`(何もない状態)だったら、プリンが地面に落っこちちゃって大惨事になるよ!」と、頑なにコードの実行を止めてきます。
ここであなたが、アシスタントの肩をポンと叩いて、こう言ったとします。
「大丈夫! そこに絶対あるから信じて!」
これが、コードにおける非nullアサーション演算子(`!`: エクスクラメーションマーク)です。
—
2. 実際のコードで見てみましょう
Web制作やフロントエンド開発でよくある例として、「HTMLの中にある特定の要素(ボタンなど)を取ってくる処理」を考えてみましょう。
// HTMLから「submit-btn」というIDを持つボタンを探してきたちえちゃん
const submitButton = document.getElementById(‘submit-btn’);
// このボタンのテキストを変えたい!
// でも、TypeScriptは「もしIDを打ち間違えてボタンが存在しなかったらどうするの?」と心配します
submitButton.innerText = ‘送信する’; // ここで赤く波線が出て怒られちゃいます!
TypeScriptの言い分ももっともです。もしHTMLの書き換えを忘れていたら、`submitButton`の中身は`null`になってしまいます。そこに `innerText` なんてプロパティを付けようものなら、画面が真っ白になるエラー(実行時エラー)が起きてしまいますよね。
ここで登場するのが「!」です。
// 「絶対にこのボタンはあるんだから!」とTypeScriptにお願いする
const submitButton = document.getElementById(‘submit-btn’)!;
// TypeScript「……それなら信じるよ!」と怒らなくなる
submitButton.innerText = ‘送信する’;
変数や関数の後ろに `!` をポンと置くだけ。たったこれだけで、TypeScriptは「この値は絶対に`null`でも`undefined`でもない」と信じ込んで、エラーの赤波線を引っ込めてくれます。
—
3. でも、ちょっと待って!「!」は「劇薬」なんです
「なんだ、じゃあエラーが出たらとりあえず `!` をつければ解決じゃん!」
そう思った方、ちょっと待ってくださいね。ここからが一番大切なプロとしての視点です。
先ほどのスーパーのたとえ話に戻りましょう。
あなたが「絶対にエコバッグがあるから大丈夫!」と自信満々でプリンを放り投げたとします。しかし、もしうっかり本当にエコバッグを家に忘れていたとしたらどうなるでしょうか?
プリンは床に激突し、パックは割れ、大惨事になりますよね。
TypeScriptの `!` もこれと全く同じです。
`!` は、「プログラムのバグ(間違い)をその場で直したわけではなく、TypeScriptの警告の口を無理やり塞いだだけ」なのです。
もし、その値が実際には `null` だった場合、コンパイル(ビルド)は成功してしまいますが、いざ実際のブラウザでユーザーがそのコードを踏んだ瞬間に、突然アプリがクラッシュ(フリーズや強制終了)します。
実務の現場では、コンパイルエラーで事前に教えてもらえる方が何倍もありがたいのです。「!」を使うのは、いわば「目隠しをして綱渡りをする」ようなもの。できるだけ使わないに越したことはありません。
—
4. 「!」に頼らない、優しくて安全な書き方
じゃあ、TypeScriptに怒られないためにはどうすればいいの?
安心してください。「!」を使わなくても、もっと安全にスマートに機嫌を取る方法があります。
① 「もしあったら実行する」という優しい確認(if文)
一番おすすめなのは、ちゃんと確かめてから動く方法です。
const submitButton = document.getElementById(‘submit-btn’);
// 「もしボタンが存在していたらね」という条件をつける
if (submitButton !== null) {
// この中では、TypeScriptはボタンが確実に存在すると分かっているので怒らない!
submitButton.innerText = ‘送信する’;
} else {
console.log(‘あれ、ボタンが見つからないよ?’);
}
これなら、万が一ボタンがなくてもアプリがクラッシュせず、優しくエラーログを残すことができます。
② オプショナルチェーン(`?.`)を使う
「もしあれば実行して、なければ何もしない」というスマートな書き方もあります。これは実務でもめちゃくちゃよく使います。
const submitButton = document.getElementById(‘submit-btn’);
// 「?」をつけることで、存在すれば文字を変え、なければ何もしない(undefinedを返す)
submitButton?.innerText = ‘送信する’;
これならコードもスッキリして、安全面もバッチリですね!
—
まとめ:今日のポイント
- `!`(非nullアサーション演算子)とは?
値が絶対に `null` や `undefined` でないとTypeScriptに思い込ませる(警告を黙らせる)記号です。
- 便利だけどリスクがある
本当に値がない場合、ブラウザ上で突然アプリがクラッシュする原因になります。
- 基本は `if` 文や `?.` を使おう
「もしかしたら無いかもしれない」という前提に立ち、安全にコードを書くのがプロの技です。
「どうしてもここに値があるのが100%確実なんだ!」というごく限られた場面でのみ、スパイス程度に `!` を使うように心がけてみてください。
TypeScriptは、あなたの敵ではなく、いつもあなたのミスを未然に防いでくれる心強い相棒です。その相棒の親切心を「うるさいな!」とテープで口を塞ぐのではなく、優しく対話しながら、安全で頑丈なWebサイトを作っていきましょうね。
あなたのコーディングライフが、今日もエラーなしで快適なものになりますように!

コメント