この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、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
以上