Open4

雑記: 型ガードを用いて異なる型を区別する

jhcoderjhcoder
ts
type Error = {
  messages: string[];
};
type OtherError = {
  message: string;
};
const isError = (error: Error | OtherError): error is Error => {
  return 'messages' in error && Array.isArray(error.messages);
};

'messages' in error: このチェックは、与えられたエラーオブジェクトがmessagesというプロパティを持っているかどうかを確認する。Error型にはこのプロパティが存在しますが、OtherError型には存在しない。
Array.isArray(error.messages): このチェックは、messagesプロパティが配列であるかどうかを確認し、これは、Error型の特徴である文字列の配列であることを確認するためのもの。

jhcoderjhcoder

Discriminated Unions(タグ付きUnion)

ts
type ApiError = {
  type: 'apiError';
  messages: string[];
};

type ApiOtherError = {
  type: 'apiOtherError';
  message: string;
};

type Err = Error | OtherError;

const getErrorMessage = (error: Err) => {
  switch (error.type) {
    case 'Error':
      return error.messages.join(', ');
    case 'OtherError':
      return error.message;
    default:
      return "Unknown error";
  }
};
jhcoderjhcoder

Union TypeとType Guardの組み合わせ

ts
// エラータイプの定義
type ApiError = {
  type: 'ApiError';
  messages: string[];
};

type ApiOtherError = {
  type: 'ApiOtherError';
  message: string;
};

// Union Type
type Err = Error | OtherError;

// Type Guardの定義
function isError(error: Err): error is Error {
  return error.type === 'Error';
}

// エラーメッセージを取得する関数
function getErrorMessage(error: Err): string {
  if (isError(error)) {
    return error.messages.join(', ');
  } else {
    // OtherErrorの場合
    return error.message;
  }
}
jhcoderjhcoder

エラー処理用のクラス

ts
// 基底クラス
abstract class BaseError {
  abstract getMessage(): string;
}

// ApiErrorクラス
class Error extends BaseError {
  constructor(private messages: string[]) {
    super();
  }

  getMessage(): string {
    return this.messages.join(', ');
  }
}

// ApiOtherErrorクラス
class OtherError extends BaseError {
  constructor(private message: string) {
    super();
  }

  getMessage(): string {
    return this.message;
  }
}

// エラーインスタンスを扱う関数
function handleApiError(error: BaseError) {
  console.log(error.getMessage());
}

// 使用例
const apiError = new Error(['Error 1', 'Error 2']);
const apiOtherError = new OtherError('Other error message');

handleApiError(apiError);
handleApiError(apiOtherError);

このコードでは、BaseError 基底クラスを継承した Error と OtherError クラスを作成。それぞれのエラータイプに応じたメッセージ処理を実装。handleApiError 関数では、これらのエラーオブジェクトを引数として受け取り、ポリモーフィズムを利用してエラーメッセージを表示。これにより、エラーハンドリングのロジックを各エラークラス内にカプセル化し、コードの再利用性とメンテナンス性を向上させることができそう。