-
TS: 인터페이스 구분하기 (ft. axios)Type Script 2022. 2. 9. 21:30
인터페이스를 각 매개변수나 객체들에게 선언해주어야 타입스크립트의 가장 큰 장점, 실시간 타입검사가 가능하다.
하지만 함수에 인터페이스를 적용할 때 가끔 그 결과의 구조가 어떻게될지 모르는 경우가 있다.
그 대표적인 예가 api를 사용할 때라고 생각한다.interface iGreeting { data: string; status: number; message: string; } // 언제나 200 status 만 내려오진 않을 것이다. const setGreeting = async (): string => { const response = axios.get(www.somthing.com); return response.data; }위의 예제에서 우리가 원하는 답안은 igreeting이라는 interface를 가진다.
하지만 만일 에러객체가 response로 들어온다면 getGreeting은 response.data를 찾을 수 없을 것이고, 이는 타입에러로 연결될 것이다.사실 axios 가 제공하는 타입에는 axiosError라는 타입이 있어서 그 타입을 써도 된다. 하지만 interceptor에서 에러 객체를 다른 형태로 돌려준다고 가정해본다. 그럼 에러 객체의 인터페이스를 선언해서 or 연산자를 쓰면 해결되지 않을까?
interface iGreeting { data: string; status: string; message: string; } // error interface 추가. // axiosError 를 interceptor에서 잡아서 저런 객체로 돌려준다고 가정. interface iError { status: number, message: string, } const setGreeting = async (): string | iError => { const response: iGreeting | iError = axios.get(www.somthing.com); return response.data; }아니면 iError와 iGreeting 은 비슷하게 생겼으니 optional data를 설정해 interface를 하나로 합쳐보는 것도 가능할 것 같다.
interface iGreetingResponse { data?: string; // error 객체는 data가 없다. status: number; message: string; } const setGreeting = async (): string | iError => { const response: iGreetingResponse | iError = axios.get(www.somthing.com); return response.data; }하지만, 타입스크립트는 이 식에 불만을 가진다.
이유인즉슨, error 형태의 response가 들어올 때에는 response.data가 존재하지 않기 때문에 response.data를 돌려줄 수 없다는 것이다. 만일 insterface의 종류를 알아내는 제네릭 함수로 iGreeting 처럼 생긴 response가 나올 때만 response.data를 리턴한다면 타입스크립트도 불평하지 않을 것이다.다시 위로 돌아가서 iGreetingResponse 와 iError 두 가지의 interface를 이용하며, interface가 iGreeting 처럼 생겼는지 안 생겼는지 구분할 수 있는 제네릭 함수를 만들어준다.
interface iGreeting { data: string; status: string; message: string; } interface iError { status: number, message: string, } // T 처럼 생긴 interface를 가졌다면 그 안의 object.data를 리턴하도록 만들었다. // 만일 T 처럼 생기지 않았다면 object.data는 없는 값이기 때문에 undefined를 반환한다. const checkResponseInterface = <T>(object: T): object is T => { return object.data } const setGreeting = async (): string | iError => { const response: iGreeting | iError = axios.get(www.somthing.com); const responseData = checkResponseInterface<iGrreting>(response); if (responseData) { return response.data;'; } return response; } // responseData가 truthy라면 (존재한다면) response.data를 돌려주고 // responseData가 falsy라면 (iError의 형태로 돌아온다면) response를 통으로 돌려준다.'Type Script' 카테고리의 다른 글
javascript 와 typescript의 타입 시스템 기능 (0) 2022.01.25 타입스크립트의 union type은 수학의 union type과 조금 다르다. (0) 2022.01.17