Typescript Map 타입은 어떻게 주나?

박재성·2022년 9월 2일
0
post-custom-banner

인프런에서 따라하며 배우는 리액트 테스트를 보면서 tdd를 학습하면서 너무 괴로웠지만 너무 간단하게 해결한 이야기를 해보려고 한다.

해당 강의는 js로 진행하기 때문에 타입스크립트를 쓰는 나는 강의를 보면서 추가적으로 적용해야할 것들이 조금씩 더 있다.

일단 구현하려고 하는 부분은 장바구니에 몇 가지 옵션을 담는 로직이다. 어떤 옵션인지 그리고 수량이 얼마인지는 Map을 사용해서 데이터를 담으려고 한다!!

문제 상황

일단 context를 사용하고, Provider에 value를 담아주어야 한다. state의 초기값으로 아래와 같은 코드를 담아주어야한다.

  const orderContext = createContext();
  const [orderCounts, setOrderCounts] = useState({
    products: new Map<string, number>(),
    options: new Map<string, number>(),
  });
return (
    <OrderContext.Provider value={store}>{children}</OrderContext.Provider>
  );

원래는 위와 같은 상황에서 끝나는 줄 알았다. 하지만 stroe에 담는 값에 () => void 함수를 담아야한다. 그래서 해결했던 방법을 다시 생각해야한다.

어떻게?

orderContext의 타입을 정해야지 Provider에 올바르게 value 값을 줄 수 있다. 내가 최종적으로 담으려고 하는 데이터는 orderCounts[]이다.

일단 orderCounts의 타입을 정해야 context에 올바르게 타입을 줄 수 있기에 해당 타입에 대해 고민했다. Map 타입이 무엇인지 보기 위해 d.파일에 가서 확인해봤다.

일단 new()는 Map 타입을 가지고 있다. Map은 위 interface에서 정의를 했고, 나는 음 그렇구나를 외치며 Map의 생김새에 대해서 떠올렸다.

[[key, value], [key, value]]

아 튜플 형식으로 된 배열이구나! 일단 내가 넣어야할 데이터는 첫 번째 요소가 string, 두 번째가 number였기 때문에 이렇게 작성했다.

type MapType<T, K> = [T, k]
interface ContextType {
	products: MapType<string, number>;
    options: MapType<string, number>;
}
const OrderContext = createContext<ContextType[] | null>(null);

ㅎㅎ... 부끄럽지만 오답도 올려본다.. 왜 저렇게 했지? 하겠지만 처음 접한 당시 최선의 방법..

이렇게 했을 때 문제는 value에 값을 담았을 때 state에 담은 값과 타입이 일치하지 않아 에러를 뿜어냈다.

나는 분명 형식도 맞췄고, 값도 올바르게 줬는데 왜 틀리지 하며 한숨을 푹푹 쉬었다.

콘솔을 키고 Map을 만들어서 찍어봤다.

앗..! 내가 생각한 Map의 형태가 아니었다. 왜 나는 배열을 생각했을까 고민해봤지만 이유가 없었다. 그냥 무언가에 홀린 듯 그렇게 생각을 했다. 그래서 딥다이브를 바로 펼쳐서 Map에 대해 슬쩍 봤다.

개념은 잘 알고 있는데.. 그럼 어떻게 타입을 줘야하지 고민하면서 구글링을 해봐도 Map 자체에 대한 타입만 나오고 이를 값으로 정의하는 것은 찾지 못 했다.

다시 d.파일을 보면서 생각을 했다.

문득 하나가 보이기 시작했다.

interface Map {...}
declare var Map: MapConstructor;

아닛..! Map 자체가 타입으로 있는데? 그럼 내가 제네릭으로 만든 것은 무엇인가..!

interface ContextType {
  products: Map<string, number>;
  options: Map<string, number>;
}

Map의 제네릭에 들어갈 타입은 string, number이기 때문에 넣어주고, context를 정의할 때 ContextType[]를 주었더니 value에 그어진 줄이 사라졌다...

혹시 몰라 state에 제네릭으로 ContextType을 주었더니 같은 타입임을 증명했다.

쏴리질러~~

는 아직 아니었다. 기존의 ContextType[]() => void를 가지는 타입을 하나 만들어야한다.

기본적인 것 같지만 어떻게 타입을 주어야 하는걸까.. 공식문서를 뒤져보기로 결정했다.

결론

문제해결은 항상 주변에 있음을 기억하자.

profile
개발, 정복
post-custom-banner

0개의 댓글