useState
の引数にstring
やnumber
でなく、定義したオブジェクトやオブジェクトの配列を渡す場合、うまく推論できないことがある。
const [examples, setExamples] = useState([]);
その場合、関数呼び出し時にコンパイルエラーになる。こんな風に明示的にアノテートしてあげるとうまくいく。
type SomeExample = {
id: number
example: string
}
const [examples, setExamples] = useState<SomeExample[]>([]);
これがどんなことをやっているのか解説する。例えば以下のようなmap
関数があったとする。
function map<T, U>(array: T[], f: (item: T) => U): U[] {
let result = []
for (let i = 0; i < array.length; i++) {
result[i] = f(array[i])
}
return result
}
パラメータと戻り値がジェネリックで抽象化されているので、様々な引数を設定できる。
map(['a', 'b', 'c'], i => i === 'a')
map([1, 2, 3], i => i === 1)
引数を明示的に書くこともできる。
map<string, boolean>(['a', 'b', 'c'], i => i === 'a')
map<number, boolean>([1, 2, 3], i => i === 1)
上記のuseState
の例では、空配列のみ引数に渡していたので適切に型推論できていなかった。そのため、明示的なアノテーションが必要だったというわけ。