TypeScript + React: Typing custom hooks with tuple types
간단한 toggle hook의 예제 입니다.
export const useToggle = (initialValue: boolean) => {
const [value, setValue] = useState(initialValue)
const toggleValue = () => setValue(!value)
return [value, toggleValue]
}
export const Body = () => {
const [isVisible, toggleVisible] = useToggle(false)
return (
<>
{/* It very much booms here! 💥 */ }
<button onClick={toggleVisible}>Hello</button>
{isVisible && <div>World</div>}
</>
)
}
이 예제는 에러가 발생합니다. onClick 시에 event : MouseEvent <HTMLButtonElement, MouseEvent>
파라미터를 전달하기 때문입니다.
이는 타입이 잘못되었기 때문입니다. any[]
? 우리는 배열을 다루지 않습니다. 명시적인 튜플 타입을 만들어 주면 사용하지 않는 파라미터에 대한 에러를 없앨 수 있습니다.
Tuple 타입으로 변경합시다! Javascript에서는 배열과 Tuple을 구분할 수 없지만 Typescript는 가능합니다.
Return 타입을 명시적으로 지정합니다.
// add a return type here
export const useToggle = (initialValue: boolean): [boolean, () => void] => {
const [value, setValue] = useState(initialValue)
const toggleValue = () => setValue(!value)
return [value, toggleValue]
}
튜플을 사용하면 예상되는 요소의 갯수와 타입을 알고 있습니다. 이것은 const assertion 처럼 들리지 않습니까?
export const useToggle = (initialValue: boolean) => {
const [value, setValue] = useState(initialValue)
const toggleValue = () => setValue(!value)
// here, we freeze the array to a tuple
return [value, toggleValue] as const
}