TypeScriptの型狭め(Narrowing)と型ガードを完全解説!初心者でも理解できる安全なプログラミング
生徒
「TypeScriptで値が複数の型になれるとき、どうやって安全に処理したらよいですか?」
先生
「そのとき役立つ考え方が、型狭め(Narrowing)と型ガードです。TypeScriptが型を判断できるように導いてあげる仕組みですね。」
生徒
「型を判断できなかったら何か問題が起こるんですか?」
先生
「たとえば数値だと思って計算しようとしたら実は文字列だった、というときにエラーが発生します。だから安全に扱うためにも、型狭めと型ガードを理解しておくことが大切です。」
1. 型狭め(Narrowing)とは?
TypeScriptでは変数が複数の型を持つことがあります。これはユニオン型と呼ばれます。例えばstring | numberという型は、文字列・数値どちらでも入る状態です。このままでは、TypeScriptは「どちらの型か分からない」ため、数値向け、文字列向けの操作ができなくなります。
そこで、条件分岐などを使って「この時点では数値だよ」とTypeScriptに教えることで、型を絞り込むことができます。これを型狭め(Narrowing)と言います。プログラムがより安全になり、間違いを防げます。
function printLength(value: string | number) {
if (typeof value === "string") {
console.log(value.length);
}
}
上の例ではtypeofを使ってvalueが文字列であることを確認しているため、.lengthを安全に使えるようになります。
2. 型ガード(Type Guard)とは?
型ガードは、ある変数が特定の型であることを判定する仕組みのことです。型ガードを使うことでTypeScriptが「この条件の中ではこの型なんだ!」と理解し、型狭めを自動で行ってくれます。
型ガードは、型を守るための番犬のような存在です。「安全な型だけを中に通す!」というイメージを持つと分かりやすいです。
型ガードにはいくつか種類があり、ここでは代表的なものを紹介します。
3. 代表的な型ガードの方法
3-1. typeof を使った型ガード
数値・文字列などの基本的な型を判定します。
function showValue(x: string | number) {
if (typeof x === "number") {
console.log(x.toFixed(2));
} else {
console.log(x.toUpperCase());
}
}
typeofを使うことで、それぞれに対応したメソッドが安全に使えます。
3-2. in 演算子による型ガード
オブジェクトに特定のプロパティがあるかチェックして型を絞ります。
type Dog = { bark: () => void };
type Cat = { meow: () => void };
function speak(animal: Dog | Cat) {
if ("bark" in animal) {
animal.bark();
} else {
animal.meow();
}
}
inを使うと、どちらの動物か確実に判断できます。
3-3. 比較演算子を使った型狭め
nullやundefinedをチェックするケースでも使います。
function hello(name?: string) {
if (name !== undefined) {
console.log("Hello " + name);
}
}
これによってnameが文字列として安全に扱えます。
4. カスタム型ガード(ユーザーが作る型ガード)
自分で型判定をする関数を作ることもできます。関数が特別な形でbooleanを返すと、TypeScriptが型狭めをしてくれます。
type User = { name: string };
type Guest = { guest: true };
function isUser(obj: User | Guest): obj is User {
return "name" in obj;
}
function greet(person: User | Guest) {
if (isUser(person)) {
console.log("ようこそ!" + person.name + "さん");
} else {
console.log("ゲストの方ですね!");
}
}
obj is Userと書くことで、「この関数がtrueを返したらUser型」と理解させています。非常に便利な型ガードです。
5. なぜ型狭めと型ガードが必要なの?
型狭めと型ガードを学ぶことで、以下のメリットがあります。
- 実行時エラーを未然に防げる
- プログラムが安全に動作する
- コード補完が正確になって開発効率アップ
- 大規模なプロジェクトでも安心して型を管理できる
特に、ユニオン型を多く使うTypeScriptでは必須の考え方です。最初は難しそうに感じますが、慣れるととても強力な武器になります!