try {
// try 부분
} catch(error) { // error type is unkown
// catch 부분
}
tsc v4.4부터, try...catch에서 catch의 error object의 타입정의가 변경되었다.
기존에는 error type이 any
였지만, tsc4,4부터 error type이 unkown으로 변경되었다.
우선 any
와 unkonw
type의 차이점을 살펴보자.
TypeScript에서 any
는 모든 타입을 할당받을 수 있는 타입이다. 즉 any
타입으로 선언된 변수, argument는 모든 타입의 값이 할당될 수 있고 전달될 수 있는 것이다.
unknown
타입도 any
과 마찬가지로 모든 타입의 값이 할당될 수 있다.
하지만 조금 다른 것은 unknown
타입으로 선언된 변수는 any
를 제외한 다른 타입으로 선언된 변수에 할당될 수 없다는 것이다.
unknown
타입의 특징은 한 가지 더 있는데, unknown
타입으로 선언된 변수는 프로퍼티에 접근할 수 없으며, 메소드를 호출할 수 없으며, 인스턴스를 생성할 수도 없다. 알려지지 않은 타입이라 그런 것이다.
앞서 살펴보았듯이, 우리는 catch문의 error type이 unkown
이라는 것을 알게되었다.
따라서 우리는 이 error가 어떤 error인지 알지 못한다.
axios에서는 isAxiosError
라는 메서드가 존재한다. 이 메서드는 주어진 인자가 axios에서 발생한 error인지 판별하는 역할을 한다.
try {
const response = axios.get(url)
} catch(error) {
if (axios.isAxiosError(error) {
// axios에서 발생한 error
}
}
isAxiosError
의 type을 살펴보면
단, 여기서 type이 axios의 버전에 따라서 달라지기 때문에 알아보아야합니다.변경 사항 github
여기서는 구 버전으로 설명을 하겠습니다.
구 버전,
isAxiosError(payload: any): payload is AxiosError;
최근 버전,
isAxiosError<T = any, D = any>(payload: any): payload is AxiosError<T, D>;
이렇게 되어있다.
따라서, isAxiosError
를 사용하여 검사하고 참이 되면 들어오는 if문 안에 error의 type은 AxiosError
로 된다.
우선, Axios에서 어떻게 type이 지정되어있는지 살펴보아야 합니다.
interface AxiosError<T = any, D = any> extends Error {
config: AxiosRequestConfig<D>;
code?: string;
request?: any;
response?: AxiosResponse<T, D>;
isAxiosError: boolean;
toJSON: () => object;
}
interface AxiosResponse<T = any, D = any> {
data: T;
status: number;
statusText: string;
headers: AxiosResponseHeaders;
config: AxiosRequestConfig<D>;
request?: any;
}
최근 버전에서는 이제 설명하는 것처럼 할 필요 없이 isAxiosError
를 사용할 때 제네릭으로 type을 받기 때문에 바로 넣어주면 됩니다.
예시) ResponseDataType
try {
const response = axios.get(url)
} catch(error) {
if (axios.isAxiosError<ResponseDataType, any>(error) {
// axios에서 발생한 error
}
}
최근 버전이 아니라면 따로 resonse data의 type을 제네릭으로 받아주지 않기 때문에 함수를 하나 만들어야 합니다.
const isAxiosError = <ResponseDataType>(
error: unknown,
): error is AxiosError<ResponseDataType> => {
return axios.isAxiosError(error);
};
이처럼 제네릭으로 type을 받아서 AxiosError의 제네릭으로 전달해주는 함수를 만들어야 합니다.
이렇게 되면 ResponseDataType
의 type으로 response data의 type이 지정되게 됩니다.
interface ResponseDataType {
message: string;
code: number;
}
try {
const response = axios.get(url)
} catch(error) {
if (isAxiosError<ResponseDataType>(error) {
error.response?.data.message;
error.response?.data.code;
}
}
axios 에러에 대해서 공통적으로 처리하려다가 마주친 문제를 해결하고 axios의 라이브러리 코드를 자세히 살펴보면서 type에 대해서 파헤칠 수 있는 기회가 되었습니다. 추가로 제네릭과 unkown
의 type, unkown
과 any
의 차이에 대해서 명확하게 알 수 있었습니다.