axios 응답 인터셉터로 리턴 값 변경 시 타입에러 발생
🐞 문제상황
axios에서 interceptor를 사용해서 데이터를 바로 리턴해주도록 설정했다. 그런데 axios에서 리턴 받은 데이터 객체의 속성을 바로 사용하려고 하니 타입에러가 발생했다. 그리고 인터셉터를 적용하지 않은 것처럼 data.data.속성명을 작성했더니 타입에러가 뜨지 않았다.
// utils/api.ts
const api = axios.create({
baseURL: 'http://baseurl',
timeout: 1000 * 30,
})
api.interceptors.response.use(
(response) => {
return response.data // 응답으로 받은 response의 data를 리턴값으로
},
)


배경지식 1. interceptor
- 인터셉터란?
axios로 요청 또는 응답을 처리하기 전(then또는catch전)에 공통적인 로직을 설정해주는 것.
보통 요청 인터셉터에서는 공통 헤더를 추가하는 작업을,
응답 인터셉터에서는 리턴 데이터 가공, 특정 응답상태 처리, 에러처리 공통화 등의 작업을 한다.
// 요청 인터셉터 - 헤더에 토큰 추가
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
// 응답 인터셉터 - 리턴 데이터 가공 및 특정 에러상태 처리
api.interceptors.response.use(
(response) => {
return response.data
},
(error) => {
if (error.response.status === 401) {
window.location.href = '/login'
}
return Promise.reject(error)
}
)
여기서 요청 인터셉터에서는 토큰을 가져와 헤더의 Authorization에 추가해서 config 객체를 수정한다(이 작업은 서버와 클라이언트 간의 인증이 필요한 요청을 처리할 수 있도록 인증정보를 포함하는 작업이다)
- config란? Axios 요청객체. 요청을 만드는데 필요한 옵션들이 있다. method, baseURL, header, params 등// config(api 요청 시 필요한 옵션들이 있는 객체) { url: '/user', method: 'get', baseURL: 'https://some-domain.com/api', headers: {'X-Requested-With': 'XMLHttpRequest'}, params: { ID: 12345 }, }
💡 해결과정
- 코드에서 보는 것처럼 응답 인터셉터에서
return response.data를 하고 있지만 실제로 api 인스턴스의 리턴 객체는 반환을AxiosResponse로 하기때문에 data 다음 속성을 바로 사용할 수 없었다.
정확하게는 실행 시 에러가 나지 않았지만 코드에서는 타입에러가 발생한 것이다.
// PostRequest.tsx
const data = await api.post<LoginResponse>('/login', formValue)
if (data.init) { // data.init에서 타입에러
onOpen()
return
}
이 프로젝트는 타입스크립트를 사용하는데, 인터셉터는 런타임에서 동작하므로 타입스크립트에서는 인터셉터의 반환값을 알 수 없었다. 그래서 axios의 기본타입인
AxiosReponse<T>를 반환해서 타입에러가 났던 것.런타임 이후에는 인터셉터가 작동을 했으므로 실제로 코드 실행 후에는 에러가 나지 않는다
배경지식 2. 타입스크립트와 런타임
타입스크립트 : 정적 타입 검사 도구로 코드 실행 전(런타임 전)에 발생하는 에러를 경고한다
타입스크립트는 자바스크립트로 컴파일된 후 코드가 실행되는데, 이 컴파일 시간에 타입 오류를 확인한다런타임 : 코드가 동작하고 결과가 나오기까지의 시간
js코드가 브라우저 또는 node.js 환경에서 실행될 때 발생하는 모든 작업 ex) 서버요청, 데이터처리
수정방향
- 타입스크립트에 인터셉터로 인해 반환값이 변경된 사실을 알려줘야한다.
- Axios 인스턴스의 반환 타입을 명시적으로 지정한다.
import axios, { AxiosInstance } from 'axios'
interface CustomAxiosInstance extends AxiosInstance {
post<T = any, R = T>(url: string, data?: any, config?: any): Promise<R>
}
const api: CustomAxiosInstance = axios.create({
baseURL: 'http://192.168.3.29:7010',
timeout: 1000 * 30,
})
- 위의 코드처럼 타입을 지정하면
api.post<LoginResponse>반환값은LoginResponse로 추론되어 에러가 발생하지 않는다.
- 리액트쿼리 사용 : axios 인스턴스의 반환타입을 지정해주지 않아도 리액트쿼리에서는 제네릭 타입 매개변수를 받아 반환값 타입을 명시적으로 정의가 가능하다.
const { mutate } = useMutation<LoginResponse>({
mutationFn: () => api.post('/users/login', { id: watch('id'), pw: watch('pw') }),
})
🎈 결과

어떤 개념을 정확히 알기위해서는 그 개념의 기초 개념을 알고 있어야한다. 매번 모든 개념을 정확히 이해하기는 어렵겠지만 내가 맞닥뜨린 문제에 대해서는 명확하게 알고 있어야한다. 이번처럼 시간이 조금 오래걸리더라도 문제에서 파생된 개념을 이해하고 넘어가도록 해야겠다.