인프런에서 따라하며 배우는 리액트 테스트를 보면서 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
를 가지는 타입을 하나 만들어야한다.
기본적인 것 같지만 어떻게 타입을 주어야 하는걸까.. 공식문서를 뒤져보기로 결정했다.
문제해결은 항상 주변에 있음을 기억하자.