애니스크립트, 타입스크립트로 변환! 🧟‍♂️🧚🏻‍♂️✨👨🏻‍💼

9rganizedChaos·2021년 10월 13일
0
post-thumbnail

이벤트 객체 타입지정

  const handleNextClick = (e: any) => {
    // e: React.MouseEvent<HTMLDivElement> 와 같이 타입지정!
    if(favoriteArtist === ""){
      setArtistAlert(true);
      setTimeout(() => {
        setArtistAlert(false);
      }, 2000);
      setPageX(e.pageX);
      setPageY(e.pageY);
    } else {
      history.push("/test");
    }
  }

리액트에서 이벤트 객체의 타입은 React 객체로로부터 꺼내 쓴다!
change 이벤트라면 ChangeEvent, Touch 이벤트라면 TouchEvent, Click 이벤트라면, ClickEvent가 아니라 MouseEvent를 사용해준다.
그리고 나서 제네릭 타입으로는 해당 함수를 이벤트로 걸어준 태그의 타입을 찾아 지정한다.
나와 같은 경우는 div 태그에 onClick 프로퍼티로 함수를 할당했으므로, HTMLDivElement 타입을 써주었다.

타입을 잘 못 설정하면 아래와 같은 오류가 발생하기도 한다.

Property 'pageX' does not exist on type 'ChangeEvent<HTMLDivElement>'.

history props의 타입 지정하기

import { RouteComponentProps } from 'react-router-dom';

function ArtistsPage({ history }: RouteComponentProps) {
  const viewState = useSelector((state: RootState) => state.viewReducer);
  const { view } = viewState;

  const dispatch = useDispatch();
  // 하단부 코드 생략
  
------------
// RouteComponentProps에 더해 props를 무언가 더 내려주었다면, extends를 써서 새 인터페이스를 선언하자!

interface landingPageInterface extends RouteComponentProps {
  handleThemeChange: Function;
}

function LandingPage(props: landingPageInterface) {
  const landingPageContainer = useRef<HTMLDivElement | null>(null);

history를 쓰면 타입스크립트에서는 당연히 prop 타입을 지정해주어야 한다. 물론이지, react-router-dom에서 이미 라우트 컴포넌트 프롭스라는 타입을 제공한다. 이를 임포트해와서 사용하자! 물론 위 코드처럼 객체 구조분해 하지 않고, props: RouteComponentProps와 같이 사용해주어도 된다!

직접 만들어놓은 API 응답 타입 지정하기

위 부분과 같은 코드인데, 사실 내가 짠 서버 API이지만, 응답 객체의 형식을 기억할 리가...^^;
그래서 콘솔로 찍어보았다!

처음에는 응답객체 전용 인터페이스나 타입이 어딘가에 미리 준비되어있을 것이라 생각했으나, 내가 못 찾은 것인지 원래 없는 것인지 모르겠으나, 결국 못 찾아서 data에 대한 부분만 따로 만들어주었다!

type result = {
  createdAt: string;
  favoriteGroup: string;
  girlGroupName: string;
  mbti: string;
  updatedAt: string;
  __v: number;
  _id: string;
}

interface resultResp {
  data: {
    results: result[]
  }
}

Number or String

        let thisMonth: number | string = new Date().getMonth() + 1;
        thisMonth = thisMonth.toString();
        if(thisMonth.length === 1){
          thisMonth = "0" + thisMonth;
        }

이 부분은 뭔가 야무지게 처리하는 방법이 있을 것도 같은데, 처음에 number로 타입을 지정해놓았다가, string으로 바꾸는 과정이 있어서 number, string 하나로 지정하면 오류가 나서 위와 같이 처리해주었다... 타입스크립트를 쓰다보면, 정말 왜 자바스크립트가 유연한 언어, 혹은 근본없는 언어라고 불리는지 조금은 알겠다...

useRef 타입 지정

  const constraintsRef = useRef(null);

interface ResultAlbumCoverProps {
  constraintsRef: MutableRefObject<null>;
  albumCoverUrl: string;
}

props로 내려 받고 나서 constraintsRefMutableRefObject<T>로 타입지정!

객체 키 타입지정

interface FitMeType {
  [key: string]: number;
}

    let findNotFitMe = (obj: FitMeType, num: number) => {
      for (let key in obj){
        if (obj[key] === 5 - num){
          notFitMeGroups.push(key);
        }
      }
      if (notFitMeGroups.length === 0){
        findNotFitMe(obj, num + 1);
      } else {
        return;
      }
    }

for...in 문을 통해 key로 객체의 값들을 순회하는데, key의 타입이 지정되지 않아 에러가 발생하였다.

[key: string]: number;와 같이 키에 타입을 지정해주니 에러가 해결되었다!

이벤트 핸들러 함수에 타입 지정

interface ResultFooterProps {
  handleKakaoBtn: React.MouseEventHandler<HTMLButtonElement>;
  handleTwitterBtn: React.MouseEventHandler<HTMLButtonElement>;
  handleFacebookBtn: React.MouseEventHandler<HTMLButtonElement>;
  handleCopyBtn: React.MouseEventHandler<HTMLButtonElement>;
}

위와 같이 React 객체를 통해 이벤트 핸들러 타입들을 꺼내 쓸 수 있다. 제네릭 타입 안에 해당 이벤트 핸들러를 할당할 태그의 타입까지 지정해준다!

useState 상태갱신함수 타입지정

interface ResultPercentProps {
  labels: string[];
  dataArr: number[];
  setLabels: React.Dispatch<React.SetStateAction<string[]>>;
  setDataArr: React.Dispatch<React.SetStateAction<number[]>>;
  handleResultComponentClick: React.MouseEventHandler;
  percentIndex?: number;
  constraintsRef?: MutableRefObject<null>;
  handleCloseBtn?: any;
}

다행이도 타입스크립트에서 useState를 사용하고 구조분해할당으로 setter 함수를 선언 할당해주고 나면!
마우스 호버로 해당함수의 타입을 살펴볼 수 있다!!

profile
부정확한 정보나 잘못된 정보는 댓글로 알려주시면 빠르게 수정토록 하겠습니다, 감사합니다!

0개의 댓글