This code works on https://flow.org/try but does not work when MyEnhancedComponent is imported elsewhere.
import * as React from 'react';
function injectProp<Props: {}>(
Component: React.ComponentType<Props>,
): React.ComponentType<$Diff<Props, { foo: number | void }>> {
return function WrapperComponent(props: Props) {
return <Component {...props} foo={42} />;
};
}
// This works in flow.org/try but not if MyEnhancedComponent is imported from another file.
const MyComponent = (props: {a: number, b: number, foo: number}) => null;
// class MyComponent extends React.Component<{
// a: number,
// b: number,
// foo: number,
// }> {}
const MyEnhancedComponent = injectProp(MyComponent);
// We don't need to pass in `foo` even though `MyComponent` requires it.
<MyEnhancedComponent a={1} b={2} />;

When I switched https://github.com/este/este to PureComponent (for another reason), Flow HOC example seems to work.
There must be something wrong about how Flow handles exported functional stateless components with Flow HOC example.
Test case. If I will rewrite https://github.com/este/este/blob/master/components/Auth.js component to functional stateless, then where Auth is imported, it does not work.
@steida does following work better:
function injectProp<Com: React.ComponentType<*>>(
Component: Com,
): React.ComponentType<$Diff<React.ElementConfig<Com>, { foo: number | void }>> {
return function WrapperComponent(props: React.ElementConfig<Com>) {
return <Component {...props} foo={42} />;
};
}
It's slightly unintuitive, but you should use either ElementProps or ElementConfig to retrieve the component props: https://flow.org/en/docs/react/types/#toc-react-elementconfig
@villesau Yep, this works! Thank you.
@calebmer How we can help with docs updating?
@villesau Btw, why no ElementProps by default? Is there any drawback?
@steida Normally you might not want to enforce passing default props to the connected component. ElementProps and ElementConfig are otherwise the same, but ElementConfig marks default props as optional.
It took me forever to learn that React.ComponentType
Btw, with Flow 0.72, we can not use * anymore. Because http://github.com/este/este is using PureComponent, I don't care.
Most helpful comment
@steida does following work better:
It's slightly unintuitive, but you should use either
ElementPropsorElementConfigto retrieve the component props: https://flow.org/en/docs/react/types/#toc-react-elementconfig