Consider the following example:
/* @flow */
import React from 'react';
declare function componentMapper<Props1, Props2>(c: ReactClass<Props1>, f: (arg: Props2) => Props1): ReactClass<Props2>;
type FirstProps = {x: string};
type SecondProps = {x: number};
class MyComponent extends React.Component {
props: FirstProps;
render() {
return <p>{this.props.x}</p>
}
}
function fn(props: SecondProps): FirstProps {
return { x: props.x.toString() };
};
const MyOtherComponent: ReactClass<{wrong: string[]}> = componentMapper(MyComponent, fn);
const fnComp = () => (<MyOtherComponent wronger={'string'} />);
This type compiles fine with flow 0.29, even though the type for MyOtherComponent is wrong. Flow should infer MyOtherComponent: ReactClass<SecondProps>, but it seems to infer ReactClass<any> instead, leading to subsequent unsafe uses.
It seems that just using ReactClass is enough to loose type safety (maybe due to the * usage)
// @flow
import React from 'react'
type Props = { x: string };
class MyComponent extends React.Component {
props: Props;
render() {
return <p>{this.props.x}</p>
}
}
const MyComponent2: ReactClass<Props> = MyComponent;
// <MyComponent /> // <= GOOD: error property `x`. Property not found in props of React element `MyComponent`
<MyComponent2 /> // <= BAD: ok for Flow though
Yes, ReactClass is known to be buggy right now. Will fix.
@avikchaudhuri
Are there any plans to fix This functionality? We have an application that depends very much on HOC (At this point, our application is blind to the errors associated with the HOC).
I suspect that the HOC will become increasingly popular to use :
https://github.com/acdlite/recompose/blob/master/docs/API.md
As of Flow 0.53, with some minor changes, this works as expected. The following code type-checks fine:
/* @flow */
import * as React from 'react';
type FirstProps = {x: string};
type SecondProps = {x: number};
declare function componentMapper<Props1, Props2>(c: React.ComponentType<Props1>, f: (arg: Props2) => Props1): React.ComponentType<Props2>;
class MyComponent extends React.Component<FirstProps, *> {
props: FirstProps;
render() {
return <p>{this.props.x}</p>
}
}
function fn(props: SecondProps): FirstProps {
return { x: props.x.toString() };
};
const MyOtherComponent: React.ComponentType<SecondProps> = componentMapper(MyComponent, fn);
const fnComp = () => (<MyOtherComponent x={10} />);
But passing the wrong props or types to the wrapping component gives an error.
I think this issue can be closed. (/cc @calebmer)
Most helpful comment
@avikchaudhuri
Are there any plans to fix This functionality? We have an application that depends very much on HOC (At this point, our application is blind to the errors associated with the HOC).
I suspect that the HOC will become increasingly popular to use :
https://github.com/acdlite/recompose/blob/master/docs/API.md