[TypeScript] Axiosのtry/catchでの例外オブジェクトを型付けする
こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、静的型付け言語TypeScriptでAxiosの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の静的型付け機能の恩恵を最も受けられるため、特に理由がなければこの方法で良いと思います。
参考
- 型を明確にしながらaxiosを使う - Qiita
- catchしたerrorがAxiosErrorか判定する
- TypeScriptの型システム - TypeScript Deep Dive 日本語版
- 一般的なエラー - TypeScript Deep Dive 日本語版
- 型ガード - TypeScript Deep Dive 日本語版
- 敗北者のTypeScript - Qiita
以上