useState 적절하게 타입정의하기

이제 React의 가장 중요한 훅 중 하나인 useState를 살펴보겠습니다.

UI에 태그를 추가하는 데 사용되는 Tags 컴포넌트를 생각해 봅시다.

export const Tags = () => {
  const [tags, setTags] = useState([]);
  return (
    <div>
      {tags.map((tag) => {
        return <div key={tag.id}>{tag.value}</div>;
      })}
      ...

상태에는 tagssetTags가 있고, setState는 빈 배열로 시작합니다.

그런 다음 각 태그에 대해 그 위에 매핑하고 tag.id 키와 태그 값을 가진 div를 반환할 것이며, 이것이 UI에 표시되는 내용이 될 것입니다.

컴포넌트에는 클릭하면 배열 끝에 새 태그가 추가되는 버튼이 있습니다.

새 태그를 전달하는 것과 함께 기존 태그를 여러 개 전달하는 setTags 호출이 있습니다.

...
      <button
        onClick={() => {
          // error inside of setTags
          setTags([
            ...tags,
            {
              id: new Date().getTime(),
              value: "New",
            },
          ]);
        }}
      >
        Add Tag
      </button>
    </div>
  );
};

하지만 현재 setTags 호출 내부에 오류가 있습니다.

문제는 tags 변수가 never 배열로 타입정의 되었다는 것입니다. useState 위로 마우스를 가져가면 빈 배열을 never 배열로 추론하기 때문에 never 배열로 추론되고 있음을 알 수 있습니다.

// hovering over `useState`
const [tags, setTags] = useState([]);

// shows
(alias) useState<never[]>

컴포넌트 내부에서 태그가 전혀 작동하지 않습니다. 즉 tag.id, tag.value 에 대한 추론이 이루어지지 않으며 여기서 setTags를 사용할 수 없습니다.

Challenge

여러분의 과제는 이 useState가 숫자타입의 id와 문자열의 value 를 가진 객체 배열로 타입정의되어 있다는 것을 어떻게 이해하게 할 수 있는지 알아내는 것입니다.