[TS]타입스크립트 Axios Error처리하는 타입 가드 (feat. 마이그레이션 중 에러)
타입스크립트에서 Axios Error를 어떻게 처리하나요?
1. any로 변경 : 하지만 타입스크립트에서 any는 사용을 지양하는 것이 좋다(타입을 주려고 타입스크립트를 쓰는 건데, any를 남발하는 것은 사용의미가 없다)
2. 타입 단언
Axios에러의 경우 error.response.data, error.response.status, error.response.headers로 구성되어있다.
아 속성 그대로 인터페이스로 타입을 정의해서 단언해주면 된다.
interface CustomError extends Error {
// name: string;
// message: string;
// stack?: string; - Error 인터페이스 프로퍼티들을 직접 쓰거나 아니면 상속해준다.
response?: {
data: any;
status: number;
headers: string;
};
}
출처: https://inpa.tistory.com/entry/TS-📘-타입스크립트-커스텀-Error-처리하기 [Inpa Dev 👨💻:티스토리]
그 다음 만들어준 인터페이스를 활용해서 err as 내가 만들어준 인터페이스 로 단언한다.
catch (err: unknown) {
const customErr = err as CustomError; // 타입 단언한 것을 변수에 넣어서 뒤에서 자주 쓰이면 재사용 될 수 있게
console.error(customErr.response?.data);
console.error(customErr.response?.status);
console.error(customErr.response?.headers);
}
출처: https://inpa.tistory.com/entry/TS-📘-타입스크립트-커스텀-Error-처리하기 [Inpa Dev 👨💻:티스토리]
그러나 우리 모두 as 또한 지양해야 한다는 것을 들어보았을 것이다.
as는 사람이 직접 붙인다는 뜻으로, 오류가 발생할 확률이 높다.
그래서 타입 가드를 활용하는 것이 베스트이다.
타입 가드
타입스크립트에서 변수의 타입을 좁히는 데에 사용되는 메커니즘.
변수의 타입을 좁혀서, 타입 시스템이 변수의 타입을 정확히 추론할 수 있게 되며, 코드 안정성을 높일 수 있다.
일반적으로 자바스크립트 문법인 typeof, instanceof, in 혹은 사용자 정의 함수를 사용한다.
typeof A
: A 타입을 문자열로 반환
A instanceof B
: B의 프로토타입 체인에 A가 포함되었는지 boolean 반환 (A가 B의 인스턴스인지 확인)
a in A
: A의 속성에 a가 있는지 boolean 값을 반환
프로젝트에서 발생한 에러 예시
다음은 내가 JS에서 TS로 마이그레이션 하다가 발생한 예시이다.
// TODO : 현재 위치 정보 얻어옴
const getLocation = useCallback(async()=>{
try{
const location = await geolocation();
return location
}catch(err){
alert(err.message);
}
},[geolocation])
try catch로 에러 나면 에러 메세지 창 띄우는데, err에 보란듯이 빨간줄.
-> 에러 타입이 unknown이기 때문!
해결 : instanceof Error로 타입을 좁혀준다.
조건문에 typeof와 instanceof를 사용하면, TypeScript는 해당 조건문 블록 내에서는 해당 변수의 타입이 다르다는 것(=좁혀진 범위의 타입)을 이해한다
여기서 CustomError 라는 타입을 만들어줘서 그 타입으로 가드를 해주면 되는데,
CustomError를 인터페이스로 만들 경우, 컴파일되면 사라지므로 Class를 이용해서 만들어줘야 한다.
// 인터페이스는 컴파일되면 자바스크립트에서 사라지기 때문에 err instanceof CusomError 가 불가능하게 된다.
// 그래서 컴파일되도 남아있는 클래스를 타입으로 이용하는 방법을 쓰는 것이다.
class CustomError_Class extends Error {
response?: {
data: any;
status: number;
headers: string;
};
}
출처: https://inpa.tistory.com/entry/TS-📘-타입스크립트-커스텀-Error-처리하기 [Inpa Dev 👨💻:티스토리]
이렇게 커스텀 에러를 만들어 준다음에
아래와 같이 수정했다.
// TODO : 현재 위치 정보 얻어옴
const getLocation = useCallback(async()=>{
try{
const location = await geolocation();
return location
}catch(err :unknown){
if(err instanceof CustomError_Class){
alert(err.message);
}
}
},[geolocation])
빨간색 줄 제거 완료!
instanceof
아래는 Class와 instanceof에 관한 예제입니다:
class Foo {
foo = 123;
common = '123';
}
class Bar {
bar = 123;
common = '123';
}
function doStuff(arg: Foo | Bar) {
if (arg instanceof Foo) {
console.log(arg.foo); // ㅇㅋ
console.log(arg.bar); // Error!
}
if (arg instanceof Bar) {
console.log(arg.foo); // Error!
console.log(arg.bar); // ㅇㅋ
}
console.log(arg.common); // ㅇㅋ
console.log(arg.foo); // Error!
console.log(arg.bar); // Error!
}
doStuff(new Foo());
doStuff(new Bar());
https://radlohead.gitbook.io/typescript-deep-dive/type-system/typeguard
타입 가드 - TypeScript Deep Dive
TypeScript는 JavaScript의 instanceof, typeof 연산자를 이해할 수 있습니다. 즉 조건문에 typeof와 instanceof를 사용하면, TypeScript는 해당 조건문 블록 내에서는 해당 변수의 타입이 다르다는 것(=좁혀진 범위
radlohead.gitbook.io