【入門編】 インデックスアクセス型とユニオン型の組み合わせ – TypeScript実践ガイド

やあ、ようこそ!TypeScriptの世界へ。私はこれまで数えきれないほどのプロジェクトで、コードが悲鳴を上げている現場を救ってきたチーフアーキテクトです。

TypeScriptを学び始めたばかりのあなたは、きっと「型って、なんだかルールが厳しくて、自由を奪われる気がする……」なんて不安に思っているかもしれませんね。でも、大丈夫。TypeScriptはあなたを縛る鎖ではなく、暗闇を照らす「懐中電灯」なんです。

今日は、その懐中電灯をさらに便利に使いこなすための「インデックスアクセス型」と「ユニオン型」の魔法の組み合わせについてお話しします。

難しい言葉に聞こえるかもしれませんが、実はこれ、「お弁当のメニューから、好きなおかずだけを選んでアレルギー成分をチェックする」くらい、直感的で優しい仕組みなんですよ。リラックスして読み進めてくださいね。

—

1. まずは「インデックスアクセス型」を思い出そう

例えば、あなたがスマートフォンの設定画面を作っているとしましょう。そこには「ユーザー名(文字列)」や「通知設定(オン/オフ)」といった情報があります。

// これが私たちの「設定表(型)」です
type AppConfig = {
userName: string; // ユーザー名
isNotificationsOn: boolean; // 通知設定
retryCount: number; // 失敗した時の再試行回数
};

ここで、「`userName` の型ってなんだっけ?」と調べたい時、TypeScriptではこう書けます。

// AppConfigの中から ‘userName’ の型だけを取り出す
type NameType = AppConfig[‘userName’]; // 結果は string 型!

これがインデックスアクセス型です。「`AppConfig`という箱の、`’userName’`という引き出しの中身は何?」と聞いているようなものですね。

—

2. もっと欲張りに!「ユニオン型」とのコンビネーション

さて、ここからが本番です。
「名前だけじゃなくて、通知設定の型も一緒に知りたいな」と思った時、あなたならどうしますか? 一つずつ別々に定義するのは、ちょっと面倒ですよね。

そこで登場するのが、複数の候補を「または(|)」でつなぐユニオン型です。

インデックスアクセスの `[ ]` の中に、このユニオン型を放り込んでみましょう。

// ‘userName’ または ‘isNotificationsOn’ の型を取り出したい!
type NameOrNotify = AppConfig[‘userName’ | ‘isNotificationsOn’];

これ、実はTypeScriptの中ではこんなことが起きています。

1. `AppConfig[‘userName’]` を探す → string だ!
2. `AppConfig[‘isNotificationsOn’]` を探す → boolean だ!
3. 見つけたものを合体させる → string | boolean

つまり、`NameOrNotify` 型は、「文字列か、真偽値のどちらかであればOK」という型に自動的に変身してくれるんです。

—

3. 身近な例え:ドリンクバーの注文

イメージしてみてください。あなたはファミレスのドリンクバーにいます。

  • メニュー(型):
  • コーラ:黒い液体
  • メロンソーダ:緑の液体
  • オレンジジュース:オレンジの液体

ここで、あなたが「コーラかメロンソーダを飲みたい」と注文したとします。すると、あなたのコップの中に来る可能性があるのは「黒い液体、または緑の液体」ですよね。

TypeScriptのこの手法も、全く同じ。
「このプロパティと、このプロパティの型をまとめて抽出して!」とお願いしているだけなんです。

—

4. 実践!エディタで試してみよう

さあ、お手元のエディタに貼り付けて、動きを確認してみてください。
「あ、本当に抽出できてる!」という感動が、上達への一番の近道です。

// 1. まずはベースとなる型を定義
type UserProfile = {
id: number;
name: string;
isAdmin: boolean;
tags: string[]; // 文字列の配列
};

// 2. ユニオン型を使って、複数のプロパティの型を一度に抜き出す
// ここでは id と isAdmin と tags を指定してみます
type ImportantInfo = UserProfile[‘id’ | ‘isAdmin’ | ‘tags’];

// — さあ、使ってみましょう! —

// OK: number型なので通ります
const myId: ImportantInfo = 123;

// OK: boolean型なので通ります
const myRole: ImportantInfo = true;

// OK: string[]型なので通ります
const myTags: ImportantInfo = [‘developer’, ‘ts-lover’];

// NG: string型はこの抽出リストには入っていないのでエラーになります!
// (UserProfileの ‘name’ は string ですが、抽出した ‘ImportantInfo’ には含めていないからです)
// const myName: ImportantInfo = “アーキテクト”;

—

5. なぜこれが実務で「神」なのか?

「別々に書けばいいじゃん」と思うかもしれません。でも、現場では「一箇所変えたら、全部に反映されてほしい」という場面が山ほどあります。

例えば、将来的に `id` の型が `number` から `string` に変わったとしましょう。
もしあなたが手書きで型を写していたら、すべての箇所を修正して回らなければなりません。

でも、このインデックスアクセス型を使っていれば、元の `UserProfile` を書き換えるだけで、それを使っている他の場所も自動的にアップデートされるのです。

これを私たちは「DRY(Don’t Repeat Yourself:同じことを繰り返さない)」と呼び、美しく堅牢なコードの証として大切にしています。

—

最後に:つまずきそうなあなたへ

「なんだかパズルみたいで難しいな」と感じても、全く気にする必要はありません。
最初はみんな「`[ ]` の中に `|` を書くの!?」と驚くものです。

大切なのは、「TypeScriptは、あなたが型を二度書きしなくて済むように手伝ってくれているんだ」という優しさに気づくこと。

まずは、自分の作ったオブジェクトから、2つくらいの型を抜き出す練習から始めてみてください。それができれば、あなたはもう立派なTypeScript使いへの一歩を踏み出しています。

また何か困ったことがあったら、いつでも聞きに来てくださいね。あなたのコードが、もっともっと輝くように応援していますよ!

コメント

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