이전 게시글의 훅에서 쓰인 타입을 따로 정리해보려고 한다. (TypeScript 사용 시)
타입 입히기 전
const [email, setEmail] = useState(""); const [nickname, setNickname] = useState(""); const onChangeEmail = useCallback((e) => { setEmail(e.target.value); }, []); const onChangeNickname = useCallback((e) => { setNickname(e.target.value); }, []);
타입 설정 후
type ReturnTypes<T = any> = [ T, (e: ChangeEvent<HTMLInputElement>) => void, Dispatch<SetStateAction<T>> ]; const useInput = <T = any>(initialData: T): ReturnTypes => { const [value, setValue] = useState(initialData); const handler = useCallback((e: ChangeEvent<HTMLInputElement>) => { setValue(e.target.value as unknown as T); }, []); return [value, handler, setValue]; }; export default useInput;
<T = any>(initialData: T)
useInput는 제너릭 타입 T를 받아들이는데, 이는 초기값의 타입을 나타낸다. 기본값으로 any를 사용한다.
type ReturnTypes<T = any> = [ T, (e: ChangeEvent<HTMLInputElement>) => void, Dispatch<SetStateAction<T>> ];
ReturnTypes는 타입을 포함하는 튜플을 정의한다.
T : 초기값 제네릭 타입 T의 타입을 그대로 받는다.
- any로 설정하면 초기값과 리턴값의 타입이 일치하지 않아도 에러가 뜨지 않는 문제가 안정성 보장이 x
(e: ChangeEvent<HTMLInputElement>) => void
: 입력 요소의 값이 변경될 때 호출되는 이벤트 핸들러 함수이다.
Dispatch<SetStateAction<T>> : 상태를 업데이트하는 데 사용
SetStateAction<T>는 useState 훅에서 사용되는 상태 업데이트 함수의 인자로 전달되는 값의 타입
제네릭타입(T), any 타입 차이
any: 타입 검사를 피하기 위해 사용하며, 타입 안정성을 보장하지 않아 결국 js와 똑같다.
Generic: 해당 함수나 클래스가 다양한 유형의 데이터를 처리할 수 있도록 만드는 기능이며, 타입 안정성을 보장한다.