[TypeScript] Axiosのtry/catchでの例外オブジェクトを型付けする

2021.09.21

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、静的型付け言語TypeScriptAxiosのtry/catchでの例外オブジェクトを型付けする方法を確認してみました。

Axiosのtry/catchでの例外オブジェクトで型エラーが発生する

AxiosでAPIエンドポイントなどへリクエストをする際に、Try/Catch構文でエラーをキャッチしたら、ステータスコードなどに応じた処理を実装したい場合があります。

import Axios from 'axios';

export const useGetData = async () => {
  try {
    const response = await Axios.get(`path/to/data`, {
      headers: {
        'Content-Type': 'application/json',
      },
    });
    return response.data;
  } catch (e) {
    if (e.response && e.response.status === 400) {
      console.log('400 Error!!')
    }
  }
};

その際に、例外オブジェクトがObject is of type 'unknown'.という静的エラーとなる場合があります。

下記のようにunknown型に型付けすれば良さそうなのですが解消しません。

  } catch (e: unknown) {
    if (e.response && e.response.status === 400) {
      console.log('400 Error!!')
    }
  }

対処方法

型ガード、型アサーション、型アノテーションの3通りの方法を確認してみます。

(方法1) isAxiosErrorによる型ガード

1番おすすめの方法です。

AxiosではisAxiosErrorというメソッドが用意されています。これを使うことによりエラーオブジェクトを型ガードすることができます。これにより型ガードをしたifブロック内ではeはAxiosの例外オブジェクトとして扱うことができるようになります。

import Axios from 'axios';

export const useGetData = async () => {
  try {
    const response = await Axios.get(`path/to/data`, {
      headers: {
        'Content-Type': 'application/json',
      },
    });
    return response.data;
  } catch (e) {
    if (Axios.isAxiosError(e) && e.response && e.response.status === 400) {
      console.log('400 Error!!');
      console.log(e.message); //Axiosの例外オブジェクトとして扱える
    }
  }
};

(方法2) AxiosErrorによる型アサーション

AxiosにおけるエラーはAxiosError型となります。キャッチ句の中で例外オブジェクトをアサーションすることにより、オブジェクトにアクセスできるようにしています。ただし、ifブロック内でeをAxiosの例外オブジェクトとして使用したい場合は再度型アサーションをする必要がありあす。また型アサーションは強制的な型付けであるため、実際の型と異なる場合に実行時エラーが発生する場合もあります。

import Axios, { AxiosError } from 'axios';

interface IErrorResponse {
  error: string;
}

export const useGetData = async () => {
  try {
    const response = await Axios.get(`path/to/data`, {
      headers: {
        'Content-Type': 'application/json',
      },
    });
    return response.data;
  } catch (e) {
    if (
      (e as AxiosError<IErrorResponse>).response &&
      (e as AxiosError<IErrorResponse>).response!.status === 400
    ) {
      console.log('400 Error!!')
      console.log((e as AxiosError<IErrorResponse>).message); //再度型アサーションする必要がある
    }
  }
};

(方法3) anyによる型アノテーション

anyによる型アノテーションを行った場合は、catchブロックの中ではeはあらゆる型になれる万能の型の変数として扱うことができます。しかしそれゆえに静的エラーを起こすことができなくなり、方法2以上に実行時エラーのリスクが高くなります。

export const useGetData = async () => {
  try {
    const response = await Axios.get(`path/to/data`, {
      headers: {
        'Content-Type': 'application/json',
      },
    });
    return response.data;
  } catch (e: any) {
    if (e.response && e.response.status === 400) {
      console.log('400 Error!!');
      console.log(e.message);
    }
  }
};

おわりに

TypeScriptでAxiosのtry/catchでの例外オブジェクトを型付けする方法を確認してみました。

再度言いますが1番おすすめの方法は「(方法1) isAxiosErrorによる型ガード」です。TypeScriptの静的型付け機能の恩恵を最も受けられるため、特に理由がなければこの方法で良いと思います。

参考

以上