JavaScript
flow
React

Flow逆引きReact関連タイプ3つ

注: Flow v0.68.0
注: 全部ここに書いてあることです。
https://flow.org/en/docs/react/types/

FlowはUtilityTypeなど便利な機能があります。
その中でもReact関連のタイプもかなり便利なのでシチュエーション別に3つ紹介したいとおもいます。

1. コンポーネントが受け取るプロパティの型を参照したい

React.ElementProps

import MyComponent from '.....';

function getPropsForMyComponent() React.ElementProps<typeof MyComponent> {
 ....
}

これがないと、 MyComponentのプロパティの型をexport typeしなければならない。

UtilityTypeの$Shapeと組み合わせたりすると便利な場面もあるとかないとか。

import MyComponent from '.....';

type MyComponentProps = React.ElementProps<typeof MyComponent>;

function update(diff: $Shape<MyComponentProps>)  {
  const newProps = Object.assign({}, props, diff);
}

$Shapeのドキュメントはまだないみたい

2. プロパティの型をインターフェース的につかって抽象化したい

React.ComponentType<Props>

これはマニアックなシチュエーション・・・。
こんなことしたくなること自体、なんか辛い目にあってるかもしれない。

type CommonProps = {....};

function A(props: CommonProps) {...}
function B(props: CommonProps) {...}

function getComponent(....): React.ComponentType<CommonProps> {
  return A or B;
}

function C() {
  const props: CommonProps = {....};
  const Component = getComponent(...);
  return <Component {...props} /> ; // <- この行のためのComponentType
}

Reactでどんだけ複雑なUI作ろうとしてんだよっていうツッコミが聞こえてきますが、Reactで継承を使って多様性を実現するぐらいなら、CompoentTypeを使うほうがReactらしくて良いのかなと思います。

3. props経由でコンポーネントを指定させたいが、デフォルトはdivな変数に型を付けたい

React.Node

function A({component}) {
  const Component: React.Node = component || 'div';
  render (
    <Component>FooBar</Component>
  );
}

外からコンポーネントを渡せるような仕組みにしたいときに出番がある型ですね。
react-transition-groupのcomponentプロパティみたいなケースのことです。

まとめ

FlowはさすがにFacebookが仕切ってるだけあって、React専用の便利な機能が組み込まれています。

今回はその中から、ちょっとしたデザインパターンを適用しようとしたときに出番がありそうな、 React.ElementProps<typeof X>, React.ComponentType<X>, React.Node を紹介しました。

ReactつかうならやっぱFlowがいいなぁ。