axios の型定義覚書

axios の レスポンスの型定義について、少し確認したのでメモ。

目的

axios のレスポンスについて TypeScript の型チェックが実行されるように型定義をする。
エラー時は、レスポンスの結果のプロパティを含まないので、誤ってプロパティに触らないようしたい。

想定レスポンス

  • 正常系
    1
    2
    3
    4
    5
    6
    7
    {
    "success": true,
    "errorMessage": "",
    "payload": {
    "id": 123
    },
    }
  • エラー
    1
    2
    3
    4
    {
    "success": false,
    "errorMessage": "same error message",
    }
  • これ以外に、ネットワークのエラーもあるが、これは chache で拾うので考慮しない。

プラン 1

型定義で 内容を固めてしまうパターン。

型定義 1

型定義
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type User = {
id: number
}

type BaseApiResponse = {
success: boolean
errorMessage: string
}

type SuccessResponse = BaseApiResponse & {
success: true
payload: {
user: User
}
}

type FailerResponse = BaseApiResponse & {
success: false
payload: null
}

type ApiResponse = SuccessResponse|FailerResponse

axios の利用 1

1
2
3
4
5
6
7
8
9
10
11
12
try {
const res = await axios.get<ApiResponse>("/api/resource");
if (!res.data.success) {
console.log(res.data.errorMessage)
// console.log(res.data.payload.user.id); // <= res.data.payload.user は 型チェックでエラーになる
return
}
// res.data.successがチェックされたことで、payload がnilではないのが確定
console.log(res.data.payload.user.id);
} catch {
console.error("/API ERROR/");
}

プラン 2

型を引数に内容を設定するパターン。

型定義 2

型定義
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type PayloadUser = {
user: {
id: number
}
}

type BaseApiResponse = {
success: boolean
errorMessage: string
}

type SuccessResponse<T> = BaseApiResponse &{
success: true
payload: T
}

type FailerResponse = BaseApiResponse & {
success: false
payload: null
}

type ApiUserResponse = SuccessResponse<PayloadUser>|FailerResponse

axios の利用 2

1
2
3
4
5
6
7
8
9
10
11
12
try {
const res = await axios.get<ApiUserResponse>("/api/resorce");
if (!res.data.success) {
console.log(res.data.errorMessage)
// console.log(res.data.payload.user.id); // <= 型チェックでエラーになる
return
}
// res.data.successがチェックされたことで、payload がnilではないのが確定
console.log(res.data.payload.user.id);
} catch {
console.error("/ERROR-API/");
}

型を設定せずに axios を使うと、レスポンスは any になり推論が効かない問題を解決した。

ではでは。