Flowのバージョンは0.61.0
で確認している。
propsを渡さない場合、Flowはどのように指定すればよいのか
ReactのコンポーネントのpropsにFlowで型をつける場合、以下のように書く。
type Props = { foo: string, }; class ChildComponent extends React.Component<Props> { render() { return <div>{this.props.foo}</div>; } }
class ParentComponent extends React.Component { render() { return <ChildComponent foo="hoge" />; } }
https://flow.org/en/docs/react/components/
では、このコンポーネントにはpropsを渡さない場合は、どう書けばいいのか。
propsは、何も渡されなかった場合、空のオブジェクトになる。
class ChildComponent extends React.Component<Props> { render() { console.log(this.props); // {} return <div>foo</div>; } }
class ParentComponent extends React.Component { render() { return <ChildComponent />; } }
なので、空のオブジェクトを型として設定してみる。
type Props = {};
しかしこれだと、propsを渡してもエラーがでない。
間違ってpropsを渡してしまった場合はエラーを出してくれないと、型として機能していない。
結論を書くと、以下のように定義すればよい。
type Props = {||};
これは、Exact object types
という表記を使って「空のオブジェクト」を定義したものである。
Exact object types
Flowでは通常、指定していないプロパティがオブジェクトに含まれていても、エラーにはならない。
例えば下記の例では、引数として渡したオブジェクトに指定していないプロパティ(boo
)が含まれているが、エラーにはならない。
// @flow function method(obj: {foo: string}) { return obj; } method({ foo: '1', // Works! boo: 2, // Works! });
先程のpropsのケースも、これが原因だった。
空のオブジェクトを指定した場合、それはむしろ、あらゆるプロパティを許容することになってしまう。
// @flow function method(obj: {}) { return obj; } method({ foo: '1', // Works! boo: 2, // Works! });
これを防ぎ、厳密にオブジェクトを定義したいときに使うのが、Exact object types
である。
{|
と|}
で囲めばよい。
// @flow function method(obj: {|foo: string|}) { return obj; } method({ foo: '1', // Works! boo: 2, // Error! });
そのため、空のオブジェクトは中に何も書かず{||}
と定義すればよい。
この場合、空のオブジェクト以外が渡された場合はエラーを出してくれる。