I have a custom hook called useDropdownSelection. It’s fairly simple. Here’s the code:
import { useState } from 'react'
export const useDropdownSelection = (initialValue: string) => {
const [selectedOption, setSelectedOption] = useState<string>(initialValue)
const handleClick = (event: React.MouseEvent<HTMLLIElement>) => {
const target = event.target as HTMLElement
setSelectedOption(target.innerText)
}
return [selectedOption, handleClick]
}
As you can see, the handleClick function is of type (event: React.MouseEvent<HTMLLIElement>) => void
But when I import it to my index.tsx, the handleClick function, for whatever reason, becomes of type string | ((event: MouseEvent<HTMLLIElement, MouseEvent>) => void)
const [selectedDropdownOption, handleDropdownClick] = useDropdownSelection('Most upvotes') // const handleDropdownClick: string | ((event: MouseEvent<HTMLLIElement, MouseEvent>) => void). WHY?
Why is this happening?
I assume it has something to do with the fact that I’m returning an array?
>Solution :
It’s because you don’t specify that useDropdownSelection is going to return array of specific types for each indexes, so TS assumes that each index may contain both callback and string value.
check example below:
const f = (s: string) => {
const n: number = 5;
return [s, n];
}
const result = f('s');
result is a (string | number)[] type. To explicitly inform that it’s going to be [string, number] you have to implement it like below:
const f = (s: string): [string, number] => {
const n: number = 5;
return [s, n];
}
const result = f('s'); // type is [string, number]
Syntax presented above is similar to one that is implemented by useState.
So in your example explicitly type return value of a hook:
export const useDropdownSelection = (initialValue: string): [string, (event: MouseEvent<HTMLLIElement, MouseEvent>) => void] => {...}