TypeScriptのEnum: 関数やジェネリック型で賢く活用

2024-05-24

TypeScriptにおけるEnumをパラメータとして使用する

Enumをパラメータとして使用する基本例

enum Color { Red, Green, Blue } // 列挙型を定義

function printColor(color: Color) { // Enum型をパラメータとして使用する関数
  console.log(color); // 例: "Red"
}

printColor(Color.Red); // 関数呼び出し

この例では、Colorという列挙型を定義し、RedGreenBlueという値を持つようにしています。 printColorという関数は、Color型の引数を受け取り、コンソールにその値を出力します。

関数シグネチャにおけるEnumパラメータの利点

  • 型安全性: コンパイラは引数が確実にColor型のいずれかの値であることを確認するため、誤った型の値が渡されるのを防ぎます。
  • コードの読みやすさ: 関数の引数が何を表しているのかを、コードを見ただけで理解しやすくなります。
  • メンテナンス性: コードを変更する際に、どの型の値が渡されているのかを把握しやすくなります。

ジェネリック型におけるEnumパラメータの使用

Enumをジェネリック型の制約として使用することで、型安全なコードをさらに汎用化することができます。

enum Shape { Circle, Rectangle, Triangle } // 列挙型を定義

function getArea<T extends Shape>(shape: T, dimensions: [number, number]): number {
  switch (shape) {
    case Shape.Circle:
      return Math.PI * dimensions[0] * dimensions[0];
    case Shape.Rectangle:
      return dimensions[0] * dimensions[1];
    case Shape.Triangle:
      return 0.5 * dimensions[0] * dimensions[1];
  }
}

const circleArea = getArea(Shape.Circle, [5, 0]); // Enum値をジェネリック型引数として渡す
console.log(circleArea); // 78.53975

この例では、Shapeという列挙型を定義し、CircleRectangleTriangleという値を持つようにしています。 getAreaというジェネリック関数は、T型の引数を受け取り、その形状と寸法に基づいて面積を計算します。 TShape型のいずれかの値に制約されているため、関数は常に正しい型の値を受け取ることになります。

その他の例

  • Enumをスイッチ式ステートメントの条件として使用して、コードをより簡潔に記述することができます。
  • Enumをオブジェクトのプロパティの型として使用して、より明確で型安全なデータ構造を定義することができます。

まとめ

Enumをパラメータとして使用することは、TypeScriptでより型安全で、読みやすく、メンテナンスしやすいコードを書くための強力なテクニックです。 関数シグネチャやジェネリック型と組み合わせることで、コードの汎用性と柔軟性をさらに高めることができます。




TypeScriptにおけるEnumをパラメータとして使用するサンプルコード

Enumをパラメータとして使用する基本例

enum Color { Red, Green, Blue } // 列挙型を定義

function printColor(color: Color) { // Enum型をパラメータとして使用する関数
  console.log(color); // 例: "Red"
}

printColor(Color.Red); // 関数呼び出し

関数シグネチャにおけるEnumパラメータの利点

enum Size { Small, Medium, Large } // 列挙型を定義

function getProduct(size: Size, price: number): number {
  switch (size) {
    case Size.Small:
      return price * 0.8;
    case Size.Medium:
      return price;
    case Size.Large:
      return price * 1.2;
  }
}

const smallProductPrice = getProduct(Size.Small, 10); // Enum値をパラメータとして渡す
console.log(smallProductPrice); // 8

説明:

この例では、Sizeという列挙型を定義し、SmallMediumLargeという値を持つようにしています。 getProductという関数は、Size型の引数とpriceという数値引数を受け取り、製品の価格を計算します。 Enum値をパラメータとして渡すことで、関数は常に正しい型の値を受け取ることになります。

ジェネリック型におけるEnumパラメータの使用

enum Shape { Circle, Rectangle, Triangle } // 列挙型を定義

function getArea<T extends Shape>(shape: T, dimensions: [number, number]): number {
  switch (shape) {
    case Shape.Circle:
      return Math.PI * dimensions[0] * dimensions[0];
    case Shape.Rectangle:
      return dimensions[0] * dimensions[1];
    case Shape.Triangle:
      return 0.5 * dimensions[0] * dimensions[1];
  }
}

const circleArea = getArea(Shape.Circle, [5, 0]); // Enum値をジェネリック型引数として渡す
console.log(circleArea); // 78.53975

その他の例

例1: スイッチ式ステートメントの条件としてEnumを使用

enum UserRole { Admin, Editor, Reader } // 列挙型を定義

function getUserPermissions(role: UserRole): string[] {
  switch (role) {
    case UserRole.Admin:
      return ['Can manage users', 'Can edit all content'];
    case UserRole.Editor:
      return ['Can edit content'];
    case UserRole.Reader:
      return ['Can read content'];
  }
}

const adminPermissions = getUserPermissions(UserRole.Admin);
console.log(adminPermissions); // ['Can manage users', 'Can edit all content']

この例では、UserRoleという列挙型を定義し、AdminEditorReaderという値を持つようにしています。 getUserPermissionsという関数は、UserRole型の引数を受け取り、そのユーザーの権限を返します。 Enum値をスイッチ式ステートメントの条件として使用することで、コードをより簡潔に記述することができます。

例2: オブジェクトのプロパティの型としてEnumを使用

enum PaymentStatus { Pending, Approved, Rejected } // 列挙型を定義

interface Order {
  id: number;
  customerName: string;
  items: string[];
  totalPrice: number;
  status: PaymentStatus; // Enum型をプロパティの型として使用する
}

const order: Order = {
  id: 123,



TypeScriptにおけるEnumをパラメータとして使用するその他の方法

型ガードを使用して、関数の引数が確実に特定のEnum値であることを確認することができます。

enum Color { Red, Green, Blue } // 列挙型を定義

function isRed(color: Color): color is Color.Red { // 型ガード
  return color === Color.Red;
}

function printColorInfo(color: Color) {
  if (isRed(color)) {
    console.log('The color is red');
  } else {
    console.log('The color is not red');
  }
}

printColorInfo(Color.Red); // "The color is red"
printColorInfo(Color.Green); // "The color is not red"

この例では、isRedという型ガード関数を作成しています。 この関数は、引数がColor.Redであるかどうかを確認します。 printColorInfo関数は、Color型の引数を受け取り、型ガードを使用して引数がColor.Redであるかどうかを確認します。

関数をオーバーロードして、異なるEnum型の引数を受け取る複数のバージョンを作成することができます。

enum Shape { Circle, Rectangle, Triangle } // 列挙型を定義

function getArea(shape: Circle, dimensions: [number]): number {
  return Math.PI * dimensions[0] * dimensions[0];
}

function getArea(shape: Rectangle, dimensions: [number, number]): number {
  return dimensions[0] * dimensions[1];
}

function getArea(shape: Triangle, dimensions: [number, number]): number {
  return 0.5 * dimensions[0] * dimensions[1];
}

const circleArea = getArea(Shape.Circle, [5]); // Enum値をパラメータとして渡す
console.log(circleArea); // 78.53975

この例では、getArea関数をオーバーロードしています。 この関数は、CircleRectangleTriangleのいずれかの型の引数を受け取り、その形状と寸法に基づいて面積を計算します。 関数オーバーロードを使用することで、コードをより明確で簡潔に記述することができます。

function getArea<T extends Shape>(shape: T, dimensions: [number, number]): number {
  switch (shape) {
    case Shape.Circle:
      return Math.PI * dimensions[0] * dimensions[0];
    case Shape.Rectangle:
      return dimensions[0] * dimensions[1];
    case Shape.Triangle:
      return 0.5 * dimensions[0] * dimensions[1];
  }
}

const circleArea = getArea(Shape.Circle, [5]); // Enum値をジェネリック型引数として渡す
console.log(circleArea); // 78.53975

この例は、前述のジェネリック型関数の例とほぼ同じですが、型パラメータを使用してshape引数がShape型のいずれかの値であることを宣言しています。 型パラメータを使用することで、コードの読みやすさと型安全性を向上させることができます。

カスタム型ガードを作成して、より複雑な条件に基づいて引数の型をチェックすることができます。

enum UserRole { Admin, Editor, Reader } // 列挙型を定義

function canEditContent(role: UserRole): boolean {
  return role === UserRole.Admin || role === UserRole.Editor;
}

function getUserPermissions(role: UserRole): string[] {
  switch (role) {
    case UserRole.Admin:
      return ['Can manage users', 'Can edit all content'];
    case UserRole.Editor:
      return canEditContent(role) ? ['Can edit content'] : [];
    case UserRole.Reader:
      return ['Can read content'];
  }
}

const editorPermissions = getUserPermissions(UserRole.Editor);
console.log(editorPermissions); // ['Can edit content']

この例では、canEditContentというカスタム型ガード関数を作成しています。 この関数は、引数がUserRole.AdminまたはUserRole.Editorであるかどうかを確認します。 getUserPermissions関数は


enums typescript


TypeScriptでスマートな条件分岐を実現!「?:」演算子とnullish coalescing operatorを使いこなそう

TypeScriptにおける「?:」演算子は、三項演算子とも呼ばれ、条件に応じて異なる値を返す便利な演算子です。JavaScriptの三項演算子とほぼ同じ役割を持ちますが、TypeScriptならではの型安全性も備えています。構文説明condition:評価する条件式。trueまたはfalseを返す必要があります。...


Angular開発者必見!ngOnInitを使いこなして効率アップ

この問題にはいくつかの原因が考えられます。コンポーネント内で@Injectable クラスをインスタンス化しているコンポーネント内で@Injectable クラスをインスタンス化すると、Angular のコンポーネントライフサイクルとは別のタイミングでインスタンス化されるため、ngOnInit が呼び出されません。...


テンプレートガードとカスタムコンポーネントで型キャストを回避!Angular 2 テンプレートにおける型キャストの代替方法

Angular 2 テンプレートで型キャストを使用するには、以下の構文を用います。ここで、expression は、型キャストする式です。asType は、式の型に変換する型です。例次の例では、number 型の式を string 型に変換します。...


TypeScript開発の効率化!オブジェクトのキーと値の型を取得する4つの方法

keyof 演算子を使うと、オブジェクトのキーの型を取得できます。この方法のメリットは、シンプルで分かりやすいコードを書けることです。デメリットは、オブジェクトの値の型を取得できないことです。この方法のメリットは、オブジェクトのキーと値の型を同時に取得できることです。デメリットは、コードが冗長になりやすいことです。...


SQL SQL SQL SQL Amazon で見る



列挙型をマスターする:TypeScript で列挙型をプログラムで操作する方法

Object. keys() を使用する最も一般的な方法は、Object. keys() 関数を使用して、列挙型のすべてのキーを取得することです。この方法は、列挙型のすべてのキーを配列として取得できますが、キーの順序は保証されません。for