やあ、こんにちは。TypeScriptの世界へようこそ。
フロントエンドの最前線でコードを書き続けていると、「型」というのは単なるエラー避けの道具ではなく、「データがどういう形をしているか」という設計図そのものなんだと痛感させられるよ。
今回は、TypeScriptの中でも少しだけ「魔法」のように感じる「再帰的型定義(Recursive Types)」についてお話ししよう。
「再帰」なんて難しそうな言葉だけど、大丈夫。実は君の身近にある、あの「マトリョーシカ」と同じ仕組みなんだ。
—
1. 「再帰的型定義」って、結局なに?
再帰的型定義を一言でいうと、「自分の定義の中に、自分自身を入れ子にすること」だ。
例えば、フォルダの中にフォルダがあり、さらにその中にフォルダがある……というディレクトリ構造を想像してみてほしい。終わりのない無限の入れ子構造を、TypeScriptに「このデータはこういうルールだよ」と教えるのが、再帰的型定義の役割なんだ。
身近な例え:お買い物のレシート
君がオンラインショッピングをしたとき、カートの中身を想像してごらん。
- カートの中には「商品」が入っている。
- でも、その「商品」の中には「セット商品」が入っていて、その「セット商品」の中には、また別の「商品」が入っているかもしれない。
この「中身の構造が同じ形を繰り返している」とき、僕たちは再帰を使って型を定義するんだ。
—
2. まずはコードで見てみよう:JSON構造を例に
Web開発で一番よく出会うのは、JSONデータだよね。JSONは、値の中にオブジェクトや配列が際限なく入る可能性がある。これをTypeScriptで表現してみよう。
// 「JSONの値」という型を定義するよ
type JsonValue =
| string
| number
| boolean
| null
| { [key: string]: JsonValue } // オブジェクトの中に、またJsonValueが入る!
| JsonValue[]; // 配列の中に、またJsonValueが入る!
// これで、どんなに深い階層のデータが来ても、TypeScriptは怖がらない。
const myData: JsonValue = {
name: “お買い物リスト”,
items: [
{ name: “りんご”, price: 100 },
{ name: “ギフトセット”, contents: [“チョコ”, “クッキー”] } // 深い階層もOK!
]
};
見ての通り、`JsonValue`という型の中で、自分自身である`JsonValue`を呼び出しているよね。これが「再帰」の正体だ。
—
3. 初学者がつまずきやすい「落とし穴」
再帰的型定義を書くとき、初心者が必ずと言っていいほどぶつかる壁がある。それは「無限ループ」の恐怖だ。
もし型の中で「自分自身」を呼ぶときに、逃げ道(終了条件)を作ってあげないと、TypeScriptは「ええと、この型を解読しようとすると、またこの型が出てきて……終わらない!」とパニックを起こしてエラーを吐くんだ。
だから、「いつかは必ず、stringやnumberのような『終着点』にたどり着く」というルートを必ず用意してあげることが、この魔法を成功させるコツだよ。
—
4. 実践:ツリー構造を表現する
最後に、もう少し実用的な「メニューリスト」を例にして、再帰的なインターフェースの作り方を見てみよう。
// メニューの項目を表す型
interface MenuItem {
title: string;
// 子メニューがあるかもしれない(オプショナル)
// ここで自分自身(MenuItem)の配列を使っているよ
children?: MenuItem[];
}
const menu: MenuItem[] = [
{
title: “ホーム”,
},
{
title: “製品情報”,
children: [
{ title: “PC” },
{
title: “周辺機器”,
children: [{ title: “マウス” }, { title: “キーボード” }] // さらに深い階層!
}
]
}
];
どうだい? このように定義しておけば、メニューが何階層深くなっても、TypeScriptは「おっ、これはMenuItemのルールに従っているね」と、安心して開発をサポートしてくれるんだ。
—
最後に:あまり難しく考えすぎないで
再帰的型定義は、最初は少し頭がこんがらがるかもしれない。でも、「入れ子になった箱を、同じルールで片付ける」というイメージさえ持てれば、必ずマスターできる。
まずは、自分の書いているコードの中で「あれ、これって中身が同じ形を繰り返してるな?」と気づくところから始めてみてほしい。その気づきこそが、君をただのコーダーから、洗練されたアーキテクトへと引き上げる一歩目になるからね。
もし詰まったら、いつでも戻ってきてコードを見直そう。大丈夫、TypeScriptは君の味方だよ。応援しているよ!

コメント