TypeScript: EnumとUnionを使いこなして開発効率を向上させる

2024-04-10

TypeScriptの列挙型(Enum)と共用体(Union)

答え: 状況によって異なります。どちらにも利点と欠点があり、使い分けが必要です。

共用体(Union)とは?

複数の型をまとめて扱える型です。例えば、以下のように、数値型と文字列型を共用体で表現できます。

type MyUnion = number | string;

const myValue: MyUnion = 10; // 数値型
myValue = "Hello"; // 文字列型

列挙型(Enum)とは?

名前付きの定数を定義できる型です。例えば、以下のように、色の名前を列挙型で表現できます。

enum Color {
  Red,
  Green,
  Blue
}

const myColor: Color = Color.Red; // "Red"

共用体と列挙型の比較

機能共用体列挙型
型の安全性高い高い
読みやすさ状況による高い
コード量少ない多い
機能型ガードが必要型ガードが不要
拡張性高い低い

共用体の利点:

  • コード量が少なく、簡潔に記述できる
  • 型ガードを使って、型の安全性も確保できる
  • 読みづらい場合がある
  • 型ガードが必要

列挙型の利点:

  • 読みやすく、コードの意味が分かりやすい
  • コード量が多くなる
  • 拡張性が低い

使い分け

  • 値の数が少ない場合は、列挙型の方が読みやすく、コードの意味が分かりやすいのでおすすめです。
  • 値の数が多い場合や、動的に値を追加したい場合は、共用体の方がコード量が少なく、簡潔に記述できます。
  • 型安全性を重視する場合は、共用体と型ガードを組み合わせて使用するのがおすすめです。

例:

  • 色を表す場合は、列挙型を使う
  • ユーザーの入力値を表す場合は、共用体を使う

共用体と列挙型は、それぞれ異なる利点と欠点があります。状況に合わせて使い分けることが重要です。




type MyUnion = number | string;

function printValue(value: MyUnion): void {
  if (typeof value === "number") {
    console.log(`数値: ${value}`);
  } else {
    console.log(`文字列: ${value}`);
  }
}

const myValue1: MyUnion = 10;
printValue(myValue1); // 数値: 10

const myValue2: MyUnion = "Hello";
printValue(myValue2); // 文字列: Hello

列挙型

enum Color {
  Red,
  Green,
  Blue
}

function printColor(color: Color): void {
  switch (color) {
    case Color.Red:
      console.log("赤");
      break;
    case Color.Green:
      console.log("緑");
      break;
    case Color.Blue:
      console.log("青");
      break;
  }
}

const myColor: Color = Color.Red;
printColor(myColor); // 赤

共用体と型ガード

type MyUnion = number | string;

function isNumber(value: MyUnion): value is number {
  return typeof value === "number";
}

function printValue(value: MyUnion): void {
  if (isNumber(value)) {
    console.log(`数値: ${value}`);
  } else {
    console.log(`文字列: ${value}`);
  }
}

const myValue1: MyUnion = 10;
printValue(myValue1); // 数値: 10

const myValue2: MyUnion = "Hello";
printValue(myValue2); // 文字列: Hello

共用体と動的な値の追加

type MyUnion = number | string;

let myValue: MyUnion = 10;

// 動的に値を追加
myValue = "Hello";

console.log(myValue); // Hello
enum Color {
  Red,
  Green,
  Blue
}

// 列挙型に動的に値を追加することはできない

// 例:
// Color.Purple = "Purple"; // エラーが発生する



TypeScriptでEnumとUnionを使う他の方法

discriminated union

discriminated union は、共用体の一種で、各メンバーに識別子プロパティを追加できます。識別子プロパティを使って、メンバーを判別できます。

interface MyUnion {
  type: "number" | "string";
  value: number | string;
}

function printValue(value: MyUnion): void {
  switch (value.type) {
    case "number":
      console.log(`数値: ${value.value}`);
      break;
    case "string":
      console.log(`文字列: ${value.value}`);
      break;
  }
}

const myValue1: MyUnion = { type: "number", value: 10 };
printValue(myValue1); // 数値: 10

const myValue2: MyUnion = { type: "string", value: "Hello" };
printValue(myValue2); // 文字列: Hello

discriminated union の利点:

  • 型安全性がより高くなる
  • コードがより読みやすくなる

readonly enum

readonly enum は、列挙型のメンバー値を変更できないようにするものです。

readonly enum Color {
  Red = "red",
  Green = "green",
  Blue = "blue"
}

let myColor: Color = Color.Red;

// myColor = "purple"; // エラーが発生する

readonly enum の利点:

  • コードの安全性が高くなる
  • 意図しない値の変更を防げる
  • 値を追加できない

enum member types

enum member types は、列挙型のメンバーに個別の型を指定できるものです。

enum Color {
  Red = "red",
  Green = "green",
  Blue = "blue"
}

function getHexColor(color: Color): string {
  switch (color) {
    case Color.Red:
      return "#ff0000";
    case Color.Green:
      return "#00ff00";
    case Color.Blue:
      return "#0000ff";
  }
}

const redColor: Color.Red = Color.Red;
const hexColor = getHexColor(redColor); // "#ff0000"

// 他の色のメンバーは使用できない
// const greenColor: Color.Green = Color.Red; // エラーが発生する

typescript enums unions


Angularで子コンポーネントにコールバック関数を渡す方法:bind(this)を使用する

方法1:bind(this)を使用する親コンポーネントでコールバック関数を定義します。子コンポーネントのテンプレートで、bind(this)を使用して親コンポーネントのコールバック関数をバインドします。子コンポーネントで、@Inputデコレータを使用してコールバック関数をバインドします。...


Angular2でTypeScript列挙型値をngSwitchステートメントで使用する

このガイドを理解するには、以下の知識が必要です。TypeScriptの基本的な知識Angular2の基本的な知識ngSwitchステートメントの使用方法列挙型の定義まず、使用する列挙型を定義する必要があります。以下は、CellTypeという名前の列挙型の例です。...


TypeScriptで「Property 'assign' does not exist on type 'ObjectConstructor'」エラーが発生する原因と解決策

このエラーは、TypeScriptコードでObject. assignを使用しようとした際に発生します。Object. assignは、複数のオブジェクトのプロパティを結合する便利な関数ですが、TypeScriptではいくつかの注意点があります。...


型安全性を保ちながらコードを柔軟にする! TypeScriptにおけるジェネリック型のオプション化

ジェネリック型にデフォルト値を設定することで、ジェネリック型を省略することができます。例えば、以下のコードでは、T型にデフォルト値としてstring型を設定しています。このコードでは、foo関数を呼び出す際に、ジェネリック型を省略することができます。bar変数には数値123、baz変数には文字列"abc"が格納されます。...


TypeScript: 'index.d.ts' はモジュールではないというエラーを3つの方法で解決する

TypeScript でサードパーティ製ライブラリを使用する場合、そのライブラリの型情報を提供する . d.ts ファイルが必要となります。しかし、まれに index. d.ts ファイルが読み込まれず、以下のエラーが発生することがあります。...


SQL SQL SQL SQL Amazon で見る



Object.values() メソッドを使ってEnumの値の名前を取得する

ここでは、Enumの値の名前を取得する3つの方法について解説します。最もシンプルな方法は、enum キーワードを使用する方法です。この方法では、Enumの値の名前は、enum キーワードとドット記法を使って直接参照できます。Object. keys() メソッドを使用して、Enumのすべてのキーを取得することもできます。


TypeScript 型エイリアスとは?

型エイリアスは、既存の型に新しい名前を割り当てることができる機能です。これにより、コードをより読みやすく、理解しやすくなります。上記の例では、number 型に MyNumber という名前を割り当てています。これにより、number 型の変数を宣言する際に、より分かりやすい名前を使用することができます。