🐈

TypeScriptでオブジェクトの値からユニオン型の型定義を生成する

2024/04/29に公開

はじめに

TypeScriptでは、オブジェクトの値からユニオン型の型定義を生成できます。
この記事ではその型定義の方法と、活用方法を紹介します。

このテクニックは、TypeScriptでEnum的な値を扱う手段となります。
型によって守られたコードが作成出来たり、分岐の記述を手続き的から宣言的にできるため非常に有用だと思います。

オブジェクトの値からユニオン型の型定義を生成する

動物のリテラル型のユニオン型を定義する例

export const Animal = {
  dog: "DOG",
  cat: "CAT"
} as const

export type Animal = (typeof Animal)[keyof typeof Animal];
// export type Animal = "DOG" | "CAT";

上記のように定義することで、Animalという型を使用しつつ、Animal.dogという形で値を代入することができます。

const animal: Animal = Animal.dog;
// animal = "DOG"

便利です🥰

ユニオン型を活用する

ユニオン型を活用することで、値ごとに出力する値を変えたり、実行する関数を変えることができます。

例1: 動物の種類に合わせて、絵文字(🐕 | 🐈)を出力する

export const AnimalEmoji: Record<Animal, string> = {
  [Animal.dog]: "🐕",
  [Animal.cat]: "🐈"
} as const
const animal: Animal = Animal.dog;
const emoji = AnimalEmoji[animal];
// emoji = 🐕

オブジェクトのプロパティにアクセスしてます。宣言的な記述になり、if文やswitch文を使用する必要がなくなりました。🥰🥰

例2: 動物の種類に合わせて、実行する関数を変える

export const AnimalBark: Record<Animal, () => void> = {
  [Animal.dog]: () => {
    console.log("ワンワン!");
  },
  [Animal.cat]: () => {
    console.log("ニャーニャー!");
  },
} as const;
const animal: Animal = Animal.dog;
AnimalBark[animal]();
// console.log("ワンワン!");

if文やswitch文を使わず処理を分岐させることができました🥰

おわりに

分岐の記述を手続き的から宣言的にできるっていいですね。
この記事で紹介したようなユーティリティ型や型演算子を使えるところが、TypeScriptの型システムの面白いところだなと思います🥰

コラボスタイル Developers

Discussion