【入門編】 等価性チェックによる型ガード – TypeScript実践ガイド

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

「よし、TypeScriptを書くぞ!」と意気込んでコードを書き始めたものの、赤色の波線(型エラー)に阻まれて、「なんだこれ、動かないじゃないか……」と頭を抱えてしまった経験、ありませんか? 大丈夫です、最初はみんなそこを通ります。私も昔はよくエラーと睨めっこしてコーヒーを飲んでいました。

TypeScriptの最大の魅力であり、時に厳しく立ちはだかる壁が「型(かた)」の存在です。JavaScriptのノリで自由に書きたいのに、TypeScriptは「おいおい、ここは文字列なのか数値なのかハッキリしてくれよ!」と聞いてきます。

今回は、そんなTypeScriptの厳しさとうまく付き合うための第一歩、「等価性チェックによる型ガード」についてお話しします。お買い物のレジでのやり取りをイメージしながら、肩の力を抜いて一緒に見ていきましょう!

—

1. 型ガードってなに? 身近な例えでお話します

突然ですが、大きなおもちゃ箱を想像してください。
その中には、プラスチックのブロックもあれば、柔らかいぬいぐるみも、お菓子もごちゃ混ぜに入っています。

あなたがいま、「硬いブロックで遊びたい!」と思ったとき、おもちゃ箱から手探りで掴んだものが、もしぬいぐるみだったら……「これじゃない!」ってなりますよね。

プログラムの世界もこれとまったく同じです。
変数の中に「文字」が入っているのか、「数字」が入っているのか、あるいは「本当になんにもない(nullなど)」のか分からない状態のまま、突然「文字を大文字にする処理をして!」と命令すると、プログラムはパニックを起こしてエラーを出してしまいます。

そこで登場するのが「型ガード(Type Guard)」です。
これは、おもちゃ箱から取り出したものに対して、「君、本当にブロックかい?」と事前にチェックする門番のようなもの。

なかでも、一番シンプルで強力なのが、普段のJavaScriptでもよく使う `===` や `!==` といった等価性チェック(中身が同じかどうかの比較)を使った型ガードです。

—

2. 実際にコードを書いてみよう!

百聞は一見に如かず。実際にエディタを開いたつもりで、コードを見てみましょう。
ここでは、「画面に表示するメッセージ」を扱う場面を想像してください。このメッセージは、文字(string)のときもあれば、まだ読み込み中だから「loading」という特定の文字、あるいは何もない(null)かもしれません。

// メッセージの型を定義します(いろんな可能性が混ざっている状態)
type MessageState = string | “loading” | null;

function displayMessage(message: MessageState) {
// ここで等価性チェック(===)を使います!

// パターン1: “loading” と完全に一致するか?
if (message === “loading”) {
// TypeScriptはこの中に入った瞬間、「この message は絶対に ‘loading’ だな」と理解します
console.log(“データを一生懸命読み込んでいます…少々お待ちください!”);
return;
}

// パターン2: null と一致するか?
if (message === null) {
// ここに入った瞬間、message は null だと確定します
console.log(“表示するメッセージはありません。”);
return;
}

// パターン3: 上記のチェックをすべてすり抜けたもの
// ここに到達した時点で、message は必ず通常の「文字列(string)」に絞り込まれています!

// だから、安心して文字列専用の機能(文字の長さを測る .length など)が使えます
console.log(`メッセージの長さは ${message.length} 文字です。`);
console.log(`内容: ${message}`);
}

どうでしょう? `if (message === “loading”)` や `if (message === null)` という、普段私たちが何気なく書いている条件分岐が、そのままTypeScriptへの「あ、ここから先はこういうデータ型になるからね」というサイン(型ガード)になっているんです。

特になんの難しい呪文も使っていませんよね。これなら今日からすぐに実務で使えそうです。

—

3. つまずきやすいポイントと「大丈夫ですよ」のフォロー

ここで、初心者の人がよくハマる「落とし穴」を一つだけシェアしておきます。

落とし穴:「あれ、絞り込めてない……?」

たまに、次のようなコードで「なんでエラーになるの!?」と悩む人がいます。

function processValue(value: string | number) {
// 「文字か数字のどちらかだけど、たぶん文字だろう」となんとなく処理しようとする
// エラー:Property ‘toUpperCase’ does not exist on type ‘string | number’.
console.log(value.toUpperCase());
}

TypeScriptは優柔不断な状態(文字か数字か分からない状態)のとき、どちらの専用機能も使わせてくれません。「安全性が確認できるまでは、危ないから触っちゃダメ!」という親心です。

解決策

ここでも今回のテーマである等価性チェックや、後々学ぶ `typeof` などを使って、「いま君はどのタイプ?」と明示してあげる必要があります。

function processValue(value: string | number) {
// もし型が string なら…とチェックする(※ここでは typeof を使っていますが基本は一緒です)
if (typeof value === “string”) {
// これで TypeScript も安心!
console.log(value.toUpperCase());
} else {
// こっちは自動的に number に絞り込まれます
console.log(value.toFixed(2));
}
}

「エラーが出た=TypeScriptに嫌われている」ではなく、「あ、まだ型が確定してなくて心配してくれているんだな」と捉えてあげてください。等価性チェック(`===`)を使って「これと一緒だよね?」と教えてあげるだけで、TypeScriptは急に優しく「それなら安心だね!」と許可を出してくれます。

—

4. まとめ:焦らず、一歩ずつ進んでいきましょう

今回は、等価性チェック(`===` や `!==`)を使った型ガードの基本についてお話ししました。

  • 型ガードとは?:ごちゃ混ぜのデータの中から、「これだよね?」と特定の種類に絞り込むテクニック。
  • 等価性チェック:`if (value === “特定の値”)` と書くだけで、TypeScriptが自動的に型を安全に理解してくれる。
  • エラーが出ても大丈夫:それはTypeScriptがあなたのコードの安全を守ろうとしてくれている証拠。

最初から完璧に型を使いこなせる人なんていません。現場のプロたちも、日々「おっと、ここで型が合わないな」と独り言をつぶやきながらコードを書いています。

まずは、身近な条件分岐を書くときに、「あ、この `===` のおかげでTypeScriptが安心してるんだな」ということを片隅に置きながら、楽しくコードを書いてみてくださいね。あなたのTypeScriptライフを、シニアアーキテクトとしてこれからも応援しています!

コメント

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