Flow Typing a Higher Order Component (HoC) While Injecting and Using Child Props

I was recently adding Flow typing to a HoC and ran into a specific use case.  The HoC injected its own function into the child component while also using of the of child props in the injected method.  So here's how to properly flow type it so that consumer of the HoC will enforce the typing of the child.

First, add the type for the prop you will be injecting into the child
type InjectedProps = {
    myInjectedMethod: () => void
};
Second, add the type for the prop you need to use from the child
type OwnProps = {
    videoId: number
};
Last, update the HoC wrapper as follows
function myHOC <PassedProps: {} & OwnProps>(
    WrappedComponent: React.ComponentType<PassedProps>
  ): React.ComponentType<$Diff<PassedProps, InjectedProps>> {

  class Wrapper extends React.Component<PassedProps> {
 

Here's what each of those lines is doing:

This is ensuring that for the calling of this HoC, we enforce the typing of the child and add the requirement for our own props.
function myHOC <PassedProps: {} & OwnProps>(
This simply passes along the typing of the child component.
    WrappedComponent: React.ComponentType<PassedProps>
This declares that we will return the prop types of the child, minus the injected props we will provide.
  ): React.ComponentType<$Diff<PassedProps, InjectedProps>> {
Putting it all together, here is our final flowtyped HoC.
// @flow

const React = require('react');

type InjectedProps = {
    myInjectedMethod: () => void
};

type OwnProps = {
    videoId: number
};

function myHOC <PassedProps: {} & OwnProps>(
    WrappedComponent: React.ComponentType<PassedProps>
  ): React.ComponentType<$Diff<PassedProps, InjectedProps>> {

  class Wrapper extends React.Component<PassedProps> {

      myInjectedMethod() {
          const {videoId} = this.props;
          //... use videoID here
      }

    render() {
        return <WrappedComponent myInjectedMethod={this.myInjectedMethod} {...this.props} />;
    }
  }

  return Wrapper;
}

module.exports = myHOC;

Leave a Reply

Your email address will not be published.