Flow requires type annotation of props in HOC

1.2k views Asked by At

I'm struggling with types of injected props by HOC.

It's just simple, in App Component, there are two props: title and message.

However title is provided by HOC.

Here's the code for this:

/* @flow */
import React, { Component } from 'react';
import type { ComponentType } from 'react';

interface AppProps {
    title: string;
    message: string;
}

class App extends Component<AppProps, {}> {
    static defaultProps = {
        message: 'Helloworld'
    }
    render() {
        return (
            <div>
                <div>Title: {this.props.title}</div>
                <div>Message: {this.props.message}</div>
            </div>
        );
    }
}

function injectProp<Props: {}>(
    Component: ComponentType<{ title: string } & Props>
): ComponentType<Props> {
    return function EnhancedComponent(props: Props) {
        return <Component title="Hello" {...props} />;
    }
};

export default injectProp(App);

It seems fine, however when I run the flow, it fails with

Missing type annotation for Props.

32| export default injectProp(App);

So I tried this, but no luck:

export default injectProp<AppProps>(App);

Now I got bunch of error messages.

> [email protected] flow F:\dev\web\proptype-test
> flow

Error ----------------------------------------------------------------------------------- src/js/components/App.js:32:16

Cannot compare boolean [1] to statics of `App` [2].

   src/js/components/App.js:32:16
   32| export default injectProp<AppProps>(App);

                      ^^^^^^^^^^^^^^^^^^^ [1]

References:
   src/js/components/App.js:10:7
   10| class App extends Component<AppProps, {}> {

             ^^^ [2]


Error ----------------------------------------------------------------------------------- src/js/components/App.js:32:27

Cannot reference type `AppProps` [1] from a value position.

   src/js/components/App.js:32:27
   32| export default injectProp<AppProps>(App);

                                 ^^^^^^^^

References:
   src/js/components/App.js:5:11
    5| interface AppProps {

                 ^^^^^^^^ [1]


Error --------------------------------------------------------------------------------------------- src/js/index.js:17:1

Cannot call `ReactDOM.render` because boolean [1] is not a React component.

   src/js/index.js:17:1
   17| ReactDOM.render(<App message="A" />, entryEl);

       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

References:
   src/js/components/App.js:32:16
   32| export default injectProp<AppProps>(App);

                      ^^^^^^^^^^^^^^^^^^^^^^^^^ [1]


Error -------------------------------------------------------------------------------------------- src/js/index.js:17:17

Cannot call `ReactDOM.render` with `<App />` bound to `element` because boolean [1] is incompatible with string [2] in
type argument `ElementType` [3].

   src/js/index.js:17:17
    17| ReactDOM.render(<App message="A" />, entryEl);

                        ^^^^^^^^^^^^^^^^^^^

References:
   src/js/components/App.js:32:16
    32| export default injectProp<AppProps>(App);

                       ^^^^^^^^^^^^^^^^^^^^^^^^^ [1]
   C:\Users\User\AppData\Local\Temp\flow\flowlib_6db8195\react.js:159:5
   159|   | string

            ^^^^^^ [2]
   C:\Users\User\AppData\Local\Temp\flow\flowlib_6db8195\react.js:167:29
   167| declare type React$Element<+ElementType: React$ElementType> = {|

                                    ^^^^^^^^^^^ [3]


Error -------------------------------------------------------------------------------------------- src/js/index.js:17:17

Cannot create `App` element because boolean [1] is not a React component.

   src/js/index.js:17:17
   17| ReactDOM.render(<App message="A" />, entryEl);

                       ^^^^^^^^^^^^^^^^^^^

References:
   src/js/components/App.js:32:16
   32| export default injectProp<AppProps>(App);

                      ^^^^^^^^^^^^^^^^^^^^^^^^^ [1]



Found 5 errors

Only showing the most relevant union/intersection branches.
To see all branches, re-run Flow with --show-all-branches

Using [email protected] and [email protected]. What am I missing? Why keep Flow complains about type annotation that doesn't needed?

1

There are 1 answers

0
modernator On BEST ANSWER

This problem will resolve by export module like this:

export default injectProp<AppProps>(App);

And update to latest version(0.86.0) will works.

I made repo for this: https://github.com/rico345100/hoc-prop-types-test

Might be helpful to people who has same issue like me.