반응형
250x250
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

짧은코딩

Axios 만들어보기 본문

TS/TS(with ZeroCho)

Axios 만들어보기

5_hyun 2022. 9. 7. 21:08

Axios 만들기

import axios, { AxiosError, AxiosResponse } from "axios";
interface Post {}
interface Created {}
interface Data {
  title: string;
  body: string;
  userId: number;
}
// date에 타입을 줄 때 그냥 any로 하면 타입핑을 포기한다는 것이다.
//따라서 제네릭을 이용해서 타입이 any가 아니여도 괜찮다.
interface Config<D = any> {
  // method는 string으로 해도 되지만 이렇게 좁혀주는 것이 더 좋다.
  method?: "post" | "get" | "put" | "patch" | "delete" | "head" | "options";
  url?: string;
  data?: D;
}
interface A {
  // await 붙는 애들은 리턴이 Promise
  // T는 response.data, R은 응답
  get: <T = any, R = AxiosResponse<T>>(url: string) => Promise<R>;
  // R은 선택이다. D는 필수이고 따라서 선택 다음엔 필수가 올 수 없다. 이럴땐 어쩔 수 없이 any를 써야한다.
  // 즉 앞에는 선택인데 뒤에는 필수면 자리 수가 안맞으니까 any로 해주는 것이다.
  post: <T = any, R = AxiosResponse<T>, D = any>(
    url: string,
    data: D
  ) => Promise<R>;
  // error은 웬만하면 unknown이 좋다.
  isAxiosError: (error: unknown) => error is AxiosError;
  (config: Config): void;
  (url: string, config: {}): void;
}

const a: A = axios;
(async () => {
  try {
    const response = await a.get<Post, AxiosResponse<Post>>(
      "https://jsonplaceholder.typicode.com/posts/1"
    );
    const response2 = await a.post<Created, AxiosResponse<Created>, Data>(
      "https://jsonplaceholder.typicode.com/posts",
      {
        title: "foo",
        body: "bar",
        userId: 1,
      }
    );
    const response3 = await a({
      method: "post",
      url: "http://jsonplaceholder.typicode.com/posts",
      data: {
        title: "foo",
        body: "bar",
        userId: 1,
      },
    });
    const response4 = await a("https://jsonplaceholder.typicode.com/posts", {
      method: "post",
      data: {
        title: "foo",
        body: "bar",
        userId: 1,
      },
    });
  } catch (error) {
    if (a.isAxiosError(error)) {
      console.error(
        (error as AxiosError<{ message: string }>).response?.data.message
      );
    }
  }
})();

1. Post, Created는 에러를 잡기 위해서 만들어줬다.

2. Data는 axios 요청의 인수인 data를 타입핑했다.

3. Config에서 data에 D 제네릭을 사용해서 any를 넣어줬다. 이렇게 해야하는 이유는 any 이외의 타입이 들어와도 괜찮기 때문이다. 만약 제네릭을 사용하지 않고 그냥 any를 했다면 다른 타입이 오지 못한다.

method는 string으로도 할 수 있지만 저렇게 구체적으로 해줘야 오타가 나도 쉽게 발견할 수 있다.

4. A는 axios이다.

get: get에서 T는 response.data, R은 response이다. 그리고 매개변수로 url 하나가 있고 await 붙은 것은 리턴값이 Promise이다.

post: post에서도 T, R의 의미는 get과 같다. post에는 매개변수에 data가 하나 더 추가되는데 앞에 T, R은 선택 값인데 D는 필수 값이다. 하지만 이러면 자리수가 맞지 않기 때문에 D = any를 하여 해결했다.

isAxiosError: isAxiosError에서 error은 any보다 unknown으로 해주는 것이 좋다.

728x90
반응형

'TS > TS(with ZeroCho)' 카테고리의 다른 글

타입을 집합으로 생각하자  (0) 2023.09.15
React with TS  (0) 2022.09.12
axios 분석  (0) 2022.09.05
npm 사이트에서 JS, TS에 따른 설치법  (0) 2022.08.25
Utility Types  (0) 2022.08.21
Comments