フックに型を付ける

戻り値の型は、フックの取扱説明書

useItems は items と loading と error を返します。型を書かないままだと、使う側にはこう見えます。

const result = useItems("shoes"); result.itmes.map(...) // 打ち間違いに誰も気付かない

戻り値に any を付けているのも同じです。any は「何でもある」ではなく「検査をやめる」という意味なので、存在しない項目を書いても通ってしまいます。フックの戻り値の型は、使う人が読む唯一の説明書です。

型に名前を付けて返す

型を独立させ、関数の戻り値として書きます。

export type UseItemsResult = { items: Item[]; loading: boolean; error: string | null; }; export function useItems(category: string): UseItemsResult { ... return { items, loading, error }; }

こう書くと3つの得があります。

  • 使う側で items と打った時点で候補が出る。綴りを間違えたらその場で赤くなる
  • 返し忘れると useItems 側が怒られる。使う側で気付くより早い
  • 型に名前が付くので、他のファイルからも UseItemsResult として読める

error の型は string ではなく string | null

エラーが無いときは何も無い、という状態を型に書きます。string | null にしておくと、使う側は if (error) で分けるまで中身を文字として扱えません。「まだ無い」を型で表しておくと、無いときの分岐を書き忘れられなくなります。

配列で返すか、オブジェクトで返すか

useState は [value, setValue] という配列を返します。2つで、順番が決まっていて、名前を呼ぶ側が自由に決めたいからです。一方カスタムフックは3つ以上を返すことが多く、順番で覚えるのは無理があります。3つ以上を返すならオブジェクトにすると考えて構いません。

演習

useItems の戻り値に型を付け、使う側で loading と error を出し分けます。

ヒント

App.tsx
mock-api.json
useItems.ts
App.tsx
mock-api.json
useItems.ts
プレビュー

できているか

  • 取得のあいだ読み込み中が出ている
  • くつが2件並んでいる
  • 件数が出ている