【入門編】 真偽値による型ガード(Truthiness Narrowing) – TypeScript実践ガイド

こんにちは!TypeScriptの世界へようこそ。チーフアーキテクトの私です。

TypeScriptを書き始めたばかりの頃って、「なんだかエラーがやたらと厳しいな…」「さっきまで普通に使えていた変数なのに、急に怒られた!」なんて壁にぶつかりがちですよね。大丈夫です、最初はみんなそこを通ります。私も昔は赤色の波線を見るたびに冷や汗をかいていました。

今日は、そんなTypeScriptの厳しさの裏側にある「優しさ」を実感できる、すごく便利で大切なテクニック「Truthiness Narrowing(トゥルフィネス・ナローイング:真偽値による型ガード)」についてお話ししますね。

名前を聞くと難しそうですが、要は「お買い物のときに、カゴの中身をチェックして『ちゃんと商品が入っているか確認する』ような自然な仕組み」のことです。一緒にゆっくり紐解いていきましょう!

—

1. そもそも「型ガード」ってなに?

Web制作やアプリケーション開発をしていると、「このデータ、文字列が入っているかもしれないし、もしかしたら何もない(`null`や`undefined`)かもしれない…」というモヤモヤした状況によく遭遇します。

TypeScriptは超・心配性な性格です。「もしかしたら何もないかもしれない箱」から、中身を確認せずにいきなり引っ張り出して使おうとすると、「危ないよ!エラーになるかもしれないよ!」と全力で止めてきます。

ここで登場するのが「型ガード」です。
「おっと、まずは中身を覗いて、ちゃんとしたデータが入っているか確かめようぜ」と安全確認をするプロセスのことです。

—

2. お買い物のカゴでイメージしてみよう

ちょっと想像してみてください。

あなたはネットスーパーでお買い物をしています。画面上の「お買い物カゴ」の中身を確認するボタンを押しました。

  • カゴの中にちゃんと商品が入っていれば、お会計に進めます。
  • もしカゴが空っぽ(nullやundefined、あるいは空文字)だったら、「まずは商品を入れてくださいね」と注意書きが表示されますよね。

TypeScriptの「Truthiness Narrowing」もこれと全く同じです。
`if (variable)` という条件分岐を書くだけで、TypeScriptは「おっ、この箱にはちゃんと中身が入っているから、これ以降はもう『無い』なんて心配しなくていいんだね!」と自動的に安全な状態へ「型を絞り込み(ナローイング)」してくれます。

—

3. 実際のコードで見てみよう

百聞は一見にしかず。エディタにコピペして試せるコードを見てみましょう。

// ユーザーの名前を受け取る関数を考えてみます。
// 名前は文字列かもしれないし、まだ未登録なら null か undefined かもしれません。
function printUserName(username: string | null | undefined) {

// ここで「if (username)」というチェックをします!
// これが Truthiness Narrowing(真偽値による型ガード)です。
if (username) {
// TypeScriptはこの中に入った瞬間、こう判断します:
// 「おっ、usernameが存在する(真である)と確認できたぞ!
// それなら null でも undefined でも空文字でもない、確実な string だな!」と。

// だから、文字列専用の便利なメソッド(大文字に変換する .toUpperCase())を
// エラーなしで安心して使わせてくれます。
console.log(`こんにちは、${username.toUpperCase()}さん!`);

} else {
// こっちは、usernameが null だったり undefined だった場合のルートです。
console.log(“ゲストさん、こんにちは!”);
}
}

// 実行してみる
printUserName(“taro”); // > こんにちは、TAROさん!
printUserName(null); // > ゲストさん、こんにちは!

どうでしょう? `if (username)` と書くだけで、TypeScriptが賢く「あ、ここから先は安全だな」と理解してくれたのです。わざわざめんどくさい長ったらしい判定を書かなくていいので、コードもスッキリしますよね。

—

4. ここだけは気をつけて!「落とし穴」の正体

このTruthiness Narrowing、とっても便利なんですが、初学者のうちは「ちょっとしたワナ」にハマることがあります。

それは、「JavaScript/TypeScriptの世界では、0や空文字(””)も『偽(falsy)』判定されてしまう」というルールです。

例えば、「未読のメッセージ数」を表す変数があったとします。

function showMessageCount(count: number | null) {
// 「0通のメッセージがある」状態のつもりで `if (count)` と書くと…?
if (count) {
console.log(`未読メッセージが ${count} 件あります!`);
} else {
console.log(“メッセージはありません。”);
}
}

// 実際に使ってみる
showMessageCount(5); // > 未読メッセージが 5 件あります!(これはOK)
showMessageCount(0); // > メッセージはありません。あれっ!?

あれれ? `0`件という数字が入っているのに、「メッセージはありません」になってしまいました。
なぜなら、JavaScriptの世界では `0` や空の文字列 `””` は、「何もない(falsy)」グループに入れられてしまうからです。

対策:本当にチェックしたいものは何かを明確にしよう!

もし「0」という数字自体は有効なデータとして扱いたい場合は、ざっくり `if (count)` と書くのをやめて、以下のように「undefinedやnullじゃないこと」を明示してあげましょう。

function showMessageCountSafe(count: number | null) {
// nullでもundefinedでもないこと(=値が存在すること)を厳密にチェックする
if (count !== null && count !== undefined) {
console.log(`未読メッセージが ${count} 件あります!`); // countが0のときもちゃんと通る!
}
}

—

5. まとめ

今日のまとめです!

1. Truthiness Narrowingとは、`if (変数)` のように書くだけで、`null`や`undefined`などの「ない状態」をスマートに弾き、安全な型へと絞り込んでくれる強力な機能。
2. お買い物のカゴに例えるなら、「中身が入っているか確認してからレジに進む」ようなもの。
3. ただし、`0` や `””`(空文字)も「偽」扱いされてしまうので、数値を扱うときなどは少しだけ注意が必要。

TypeScriptの型エラーにイライラしてしまう日もあるかもしれませんが、それはTypeScriptがあなたのコードの「安全な相棒」として隣で守ってくれている証拠です。

「ふむふむ、今はカゴの中身をチェックしてくれているんだな」とイメージしながら、ぜひ日々の開発に取り入れてみてくださいね。あなたのTypeScriptライフが、少しでも楽しく快適なものになりますように!

コメント

タイトルとURLをコピーしました