ReactでGenerics Componentを作る

React、TypeScriptでの実装の話。
Reactのコンポーネントの型付けにGenericsを使いたいケース。

したいこと

コンポーネントの型付けにGenericsを使いたい。

具体例

実際にあったのが以下のようなケース。

こんなListコンポーネントがある。

これの使い方はこう。

dataプロパティに何らかの配列を渡して、renderRowで指定された関数を使ってviewに表示する。

このdataにわたすデータは、例のようにstring型のシンプルなものもあれば、もっと複雑なユーザー情報の入った自作型のときもある。

APIを叩いて取得したデータが空のときは、emptyで指定したchildrenを表示する。

というコンポーネント。

これの何が問題なのかというと、Listの型を決めているインターフェースの中でany型を使っている点。

しかし、この2つのanyのところに実際に入る型はstringのときもあれば自作のUser型だったりもするので、一意に決まらない。

そうすると、使う側でも型を指定しなければ暗黙的にanyになってしまう。

もちろん渡すときに明示的に型を書けばなんとかはなる。

でもやっぱり、anyが残ってるのってなんかキモいよなって、思ってしまうのです。

そこで、このListコンポーネントの型に多相性をもたせたいと言うのが今回の目的。

解決策

これでいける。

こうすれば、以下のような複雑なデータ型に対しても適切に推論される。

 

ちゃんとUser型と推論されている。

やったね。

補足

ただし、この型の付け方は厳密ではない。
返しているのはReact.ReactElement型だ。

一方で、実際のReact.FC型は以下のように定義されている。

いろいろ試してみたが、あんまりうまく行かなかった。
現時点ではこの型の付け方でも問題はなさそうなのでいったんコレで良しとしとく。