Typescript Map 타입은 어떻게 주나?

박재성·2022년 9월 2일
0

인프런에서 따라하며 배우는 리액트 테스트를 보면서 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
개발, 정복

0개의 댓글