티스토리 뷰
회원가입 컴포넌트를 만들면서 input 태그에 들어가는 state들이 많아져서 공통되는 부분을 커스텀 훅으로 분리할 때, 생긴 이슈에 대해서 정리한다.
우선 타입스크립트는 변수(e.g. const hello)는 명시적으로 타입을 지정해주지 않아도 잘 추론한다. 하지만, 매개변수나 리턴값의 경우 추론을 내가 원하는 대로 해주지 못하는 경우가 많기 때문에 이때 명시적으로 써주는 것이 필요하다. 보통은 코드를 작성하다가 TS가 에러를 뱉어내며 스스로 추론하지 못할 때 그 때 타입을 선언해주면 된다.
src>hooks>useInput.ts
import { useCallback, useState, SetStateAction, Dispatch } from 'react';
type Handler = (e: React.ChangeEvent<HTMLInputElement>) => void;
// 리턴타입을 명시하지않으니 가져다 쓸 때 OR(유니언 타입)으로 명시되길래 명시
type ReturnTypes<T> = [T, Handler, Dispatch<SetStateAction<T>>];
const useInput = <T = any>(initialData: T): ReturnTypes<T> => {
const [value, setValue] = useState(initialData);
const handler: Handler = useCallback((e) => setValue(e.target.value as unknown as T), []);
// 커스텀 훅 사용하여 가져올 때 위치중요
return [value, handler, setValue];
};
export default useInput;
- 위 코드는 내가 만든 useInput 이라는 커스텀 훅이다. 우선 컴포넌트에서 커스텀훅을 갖다 쓸 때, return의 배치를 처음에는 [value, setValue, handler] 로 했다가 useState와 타입 순서가 겹쳐서 잘못하면 더 헷갈릴 수 있겠다는 생각에 handler의 위치를 2번째로 해주었다. (커스텀 훅 내에서 순서는 크게 상관없지만 갖다 쓸 곳에서는 이 순서에 맞춰줘야 한다.)
- 또한, e.target.value를 할 때, 핸들러의 매개변수 event 객체의 타입을 지정해줬음에도 e.target.value에 에러가 떠서 해결 방법을 보니 `as`(type assertion: 타입단언)을 통해 제네릭인 T 값으로 지정해주어 해결했다.
- 참고로 타입스크립트의 모든 타입이 as로 자유롭게 형변환이 가능한 게 아니라 any나 unknown만이 as로 자유롭게 형변환이 가능하다. 다만 string, boolean, number 등의 타입은 unknown으로 형변환이 가능하다. 그렇기 때문에 unknown으로 먼저 바꿔주고 그 다음 T로 타입 형변환을 해준 것이다. `e.target.value as unknown as T`
- return 부에 들어가는 구조분해할당이된 배열에 인자의 타입을 확인해봤을 때, 명시적으로 잘 잡히길래 컴포넌트에서 갖다 썼는데 컴포넌트.tsx에서 에러가 났다. 해당 컴포넌트에서 타입이 어떻게 추론되는 지 봤더니 배열 특성상 인자들의 타입이 `유니언 타입` 즉, OR 연산자처럼 되어있었다. 결국 return type을 명시하는 코드를 커스텀 훅에 추가하여 해결할 수 있었다.
<T = any>
- 제네릭에도 기본값을 넣어줄 수 있다는 것을 보여준다. (타입 중에서도 아무 값을 받을 수 있다는 것을 선언)
'Frontend > TypeScript' 카테고리의 다른 글
[CRA | craco] CRA로 만든 리액트 프로젝트 웹팩 세팅 변경하기(alias) (0) | 2023.06.10 |
---|---|
[TypeScript | router dom v6] 중첩라우팅 방법 (0) | 2023.05.31 |
[webpack] babel, TS, webpack 세팅하기 2(dev server) (0) | 2023.05.18 |
[webpack] babel, TS, webpack 세팅하기 1(+ proxy로 CORS에러 해결하기) (0) | 2023.05.17 |
[TypeScript] 다형성(polymorphism)과 제네릭 (0) | 2023.05.02 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 원티드 프리온보딩 FE 챌린지
- 원티드 3월 프론트엔드 챌린지
- text input pattern
- 원티드 FE 프리온보딩 챌린지
- 항해99프론트
- Prittier
- nvm경로 오류
- float 레이아웃
- getServerSideProps
- getStaticPaths
- 프리렌더링확인법
- 틸드와 캐럿
- 원티드 프리온보딩 프론트엔드 챌린지 3일차
- tilde caret
- 형제 요소 선택자
- 부트캠프항해
- 타입스크립트 DT
- nvm 설치순서
- grid flex
- 프리온보딩 프론트엔드 챌린지 3월
- 항해99프론트후기
- is()
- D 플래그
- 타입스크립트 장점
- fs모듈 넥스트
- aspect-ratio
- ~ ^
- 항해99추천비추천
- reactAPI
- && 셸 명령어
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함