Proper Flow type for React render method?

ffxsam picture ffxsam · Jun 30, 2016 · Viewed 16.6k times · Source

I'm curious what the proper Flow annotation is for both render methods in React classes, and simple returns in stateless functions:

const UserProfilePage = () => {
  return <div className="container page">
    <UserProfileContainer />
  </div>
};

By setting the return type intentionally incorrect (to a number), I got this error:

  8:   return <div className="container page">
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ React element: `div`
  8:   return <div className="container page">
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ React$Element. This type is incompatible with the expected return type of
  7: const UserProfilePage = (): number => {
                                 ^^^^^^ number

So, changing the code to this seems to satisfy Flow:

const UserProfilePage = (): React$Element => {
  return <div className="container page">
    <UserProfileContainer />
  </div>
};

I'm wondering if this is correct, and if so, where is this documented?

Answer

Nikita picture Nikita · Jul 3, 2016

You don't need to annotate the render method, Flow should be able to infer the output type because it knows what JSX desugars to.

Flow has a built-in React interface, where all this stuff is defined:

declare class React$Element<Config> {
  type: ReactClass<Config>;
  props: $PropsOf<Config>;
  key: ?string;
  ref: any;
}

And then

render(): ?React$Element<any>;

So if you want to provide an explicit return type of a render method, you can use that signature. Well, maybe without a question mark if know you're not returning null. Not sure if there's any effect to omitting <any>.