ohah/react18-study

타입스크립트에 대한 질문입니다.

Closed this issue · 1 comments

강사님 안녕하세요. 잘 지내셨나요? 제가 프로젝트를 하나 하고 있는데요. useState 훅에 setState 함수의 prevState를 타입을 주는 부분에서 막혀서 질문 드립니다.

image

현재는 위 사진처럼 setAuth와 setValidate는 우선 any로 해결한 상태입니다..

image

문제인 setAuth 함수는 로그인, 회원가입 페이지에서 input에 입력을 상태로 저장하는 역할이며 setValidate 함수 사용자의 입력을 검증하는 역할의 함수입니다. 이 두 함수는 로그인 페이지와 회원 가입 페이지에서 사용되는 아이디, 비밀번호 입력과 검증 로직을 재사용하기 위해서 타입을 setAtuh: React.Dispatch<React.SetStateAction> | React.Dispatch<React.SetStateAction> 그리고 setValidate: React.Dispatch<React.SetStateAction> | React.Dispatch<React.SetStateAction> 로 2개씩 준 상황입니다.

제가 생각한 prevState는 useState의 상태 타입을 prevState에 적용해주면 해결될 문제라고 생각해서 저는 다음과 같이 타입을 줘보았습니다. 하지만 다음 오류와 같이 되지 않았습니다.

image

혹시 어떤 타입을 줘야 문제가 해결될지 궁금해서 질문드립니다.

혹시 자세한 코드가 필요하실 수도 있으실 것 같아 브랜치 링크 남깁니다.
링크

해당 코드와 관련된 파일은 AuthInput, Input 컴포넌트, useValidate 커스텀훅, Join, Login 페이지입니다.

ohah commented

타입스크립트에서 current 함수를 받을때 정의하신 useState 타입이 정확히 두 개 중 어떤것인지 타입스크립트에서 해석하지 못해서 나오는 형태입니다.
콜백이

interface Auth {
  email: string;
  password: string;
  passwordConfirm: string;
}

의 형태이거나,

type LoginValidate  = {
  email:string
}

이 두개 중 무엇이 오는지 추론 할 수 없기 때문에, 타입을 모르겠다라고 경고를 띄워주는것입니다.

이런경우 as로 강제로 타입 표명을 하기도 하지만,
보통 이러한 콜백 함수의 경우에는 그렇게 하기엔 약간 어울리지 않는 느낌이 있습니다.
타이핑이 길어지기도 하니까요

함수를 여러개 넣는것이 아닌, 함수 안의 제네릭을 여러개를 넣어주는 형태로 하시면 추론이 잘 됩니다.

interface Auths {
  auth: JoinAuthIndex | LoginAuthIndex;
  validate: JoinValidateIndex | LoginValidateIndex;
  setAuth: React.Dispatch<React.SetStateAction<JoinAuth | LoginAuth>>
  setValidate:React.Dispatch<React.SetStateAction<JoinValidate | LoginValidate>>    
}

또는 해당값이 필수가 아닌 경우가 있을 수 있으니

interface Auths {
  auth: JoinAuthIndex | LoginAuthIndex;
  validate: JoinValidateIndex | LoginValidateIndex;
  setAuth: React.Dispatch<React.SetStateAction<Partial<Auth>>>
  setValidate: React.Dispatch<React.SetStateAction<Partial<Auth>>>
}

이런 형태로 넣어주셔도 추론은 가능합니다.

다만 리액트내에서 제공하는 useState를 커스텀하기 어렵기에, 위와 같은 방법이 가장 좋을 것 같아 안내 드렸지만,
개발자마다 각각 생각하는 방법 구현하는 방법이 다르고, 위의 코드보다 더 효율적이고 직관적인 코드도 있을거라 생각됩니다.
https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types

우선 발생하는 원인은 유니온타입이라는 내용에서 더 자세하게 확인하실 수 있습니다.
해당 문서를 한번 참조해보세요.