Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flow error "props is incompatible with empty" when instantiating a Component without passing any props

I have a component that is wrapped in a react-redux "connect". All the props of the component are supplied by mapStateToProps and MapDispatchToProps, so there are no "ownProps" passed to the component.

However, I get the following flow error:

Cannot create Credits element because props [1] is incompatible with empty [2].

     src/components/ChildrenView/index.js
     323│         />
     324│
     325│         {/* Credits */}
 [1] 326│         <Credits />
     327│
     328│         {/* fullscreen pictures rhat open with onClick on tge image */}
     329│         <PhotoViewer />

     flow-typed/npm/react-redux_v5.x.x.js
 [2] 110│     CP: $Diff<ElementConfig<Com>, RSP>,

Isn't props in 1 already empty??

I am using flow-typed as you can state in the error.

Here is the class definition and connect call:

type Props = {|
  ...mapStateToPropsType,
  pricingModal: typeof pricingModal,
  offlineModal: typeof offlineModal,
|}


class Credits extends React.Component<Props> { ... }


type mapStateToPropsType = {|
  balance: number,
  isVisiblePricing: boolean,
  isConnected: boolean,
  isVisibleOffline: boolean,
|}

const mapStateToProps = ({ parents, pricing, appState }: TP.State): mapStateToPropsType => ({
  balance: parents.balance || 0,
  isVisiblePricing: pricing.modalPricing,
  isConnected: appState.isConnected,
  isVisibleOffline: appState.modalOffline,
})

export default connect(mapStateToProps, { pricingModal, offlineModal })(Credits)

How can I remove this error (without using $FlowFixMe :/)?

Edit 1

If I make the following change on "connect" type definition on line 110 and 114 of react-redux_v5.x.x.js, type check works as expected.

Before:

  declare export function connect<
    Com: ComponentType<*>,
    S: Object,
    SP: Object,
    RSP: Object,
    MDP: Object,
    CP: $Diff<ElementConfig<Com>, RSP>,
  >(
    mapStateToProps: MapStateToProps<S, SP, RSP>,
    mapDispatchToProps: MDP,
  ): (component: Com) => ComponentType<$Diff<CP, MDP> & SP>

After:

  declare export function connect<
    Com: ComponentType<*>,
    S: Object,
    SP: Object,
    RSP: Object,
    MDP: Object,
    CP: $Diff<$Diff<ElementConfig<Com>, RSP>, MDP>, /*  <-- here */
  >(
    mapStateToProps: MapStateToProps<S, SP, RSP>,
    mapDispatchToProps: MDP,
  ): (component: Com) => ComponentType<CP & SP> /*  <-- here */
like image 954
Francisco Sarmento Avatar asked May 07 '18 17:05

Francisco Sarmento


3 Answers

I can't comment on James Kraus' answer because I don't have enough reputation, but I can confirm that updating to the latest version of flow (0.71) fixed it for me. I literally stumbled upon the same problem 30 minutes ago. I didn't have to update flow-typed definitions. Accept James' answer if it worked for you too.

Although, in my case, I'll still have to use $FlowFixMe because I'm on react-native and updating to any version higher than 0.67.x breaks everything else.

like image 74
Alex Borgue Avatar answered Oct 23 '22 17:10

Alex Borgue


I also can't comment because of my reputation. I have had the exact same issue as Alex Borgue. I am also stuck on flow 0.67.1 because of react-native.

This occurs when:

  1. you pass connect an object for the mapDispatchToProps argument: Looks like something is off with the connect function's lib def that takes an object for the mapDispatchToProps argument which Francisco Sarmento noted above. Flow doesn't seem to have any problems if you wire up the dispatch actions as props using a function. The lib def for that version of the connect function is subtly different, and pretty close to the edit that Francisco Sarmento made.
  2. you don't specify any props when instantiating the HOC returned by connect, (e.g. all require parameters are covered by react-redux), and
  3. you utilize the component in a separate file from where it is defined (e.g. there is an export and import involved). The Flow.org/try link that James Kraus submitted above threw me for a loop. My particular component worked as expected when i ran it using James's setup. I then noticed that my local flow didn't complain if i instantiated the HOC in the same file it was define in. Flow only spat out Cannot create XXX element because props [1] is incompatible with empty [2] when i imported the HOC into another file. I have no idea what potential implications this might have - perhaps it has no bearing on the underlying cause and is just a local environment issue.
like image 36
carlos Avatar answered Oct 23 '22 17:10

carlos


Are you using the latest version of Flow and the Typedefs? I don't see any errors when I use the latest version of Flow and the latest typedefs in a thrown-together example on Flow.org/try. If that doesn't help, try creating a working example of your problem, either on Flow.org/try (preferable) or on Github.

like image 1
James Kraus Avatar answered Oct 23 '22 17:10

James Kraus