Axios 인스턴스를 타입 추론이 가능하도록 커스텀하기

타입 추론으로 재사용성 높이기

2024-03-08 |

2

문제 인식

API response의 공통 타입은 이러합니다.

typescript

type CommonResponse<T> = { code: string; message: string; data: T; };

그래서 Axios로 API를 모듈화 할 때 다음과 같이 제네릭 타입을 반복적으로 작성해야 하는 불편함이 있었습니다. 그리고 구조분해할당해서 가져온 data를 가져와서 한뎁스 더 들어가서 return 해주어야 했어요.

typescript

export const authApi = { getLogin: async (code: string, provider: string) => { const { data } = await instance.get<CommonResponse<LoginResponse>>(`/auth/login?code=${code}&provider=${provider}`); return data.data; }, };

해결 과정

다음과 같이 Axios instance를 http 메서드 별로 한 번 더 래핑하는 객체를 작성했습니다.

typescript

const getResponseFromBody = <T>(response: AxiosResponse<CommonResponse<T>>): T => { const { data: body } = response; return body.data; }; const http = { get: <T = unknown>(...args: Parameters<Axios['get']>) => instance.get<CommonResponse<T>>(...args).then(getResponseFromBody), post: <T = unknown>(...args: Parameters<Axios['post']>) => instance.post<CommonResponse<T>>(...args).then(getResponseFromBody), patch: <T = unknown>(...args: Parameters<Axios['patch']>) => instance.patch<CommonResponse<T>>(...args).then(getResponseFromBody), put: <T = unknown>(...args: Parameters<Axios['put']>) => instance.put<CommonResponse<T>>(...args).then(getResponseFromBody), delete: <T = unknown>(...args: Parameters<Axios['delete']>) => instance.delete<CommonResponse<T>>(...args).then(getResponseFromBody), };

기본적으로 제네릭 타입으로 넘어온 타입이 CommponResponse의 generic 타입으로 넘어가게 됩니다. 그리고 리턴하는 Promise를 then 체이닝에서 getResponseFormBody가 response.data.data 의 값을 반환하도록 하고 있어요.

훨씬 말끔해졌습니다!