3
votes

I describe HOC as in this article: https://medium.com/@jrwebdev/react-higher-order-component-patterns-in-typescript-42278f7590fb

My code (HOC):

import * as React from 'react';
import Dropzone from 'react-dropzone'


export const addImage = <P extends object>(WrappedComponent: React.ComponentType<P>) => {
  return class extends React.Component {

    render() {

      return <Dropzone noClick onDrop={()=>{console.log('drop')}}>
        {({ getRootProps, getInputProps }) => (

            <div {...getRootProps()} onClick={()=>{console.log('aa')}}>
              <input {...getInputProps()} />
              <WrappedComponent {...this.props} />;
      </div>

        )}

      </Dropzone>

    }
  };
}

In other component:

addImage(<Img src={item} />)

In HOC error: '{ children?: ReactNode; }' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'object'

How to fix the error?

4

4 Answers

3
votes

I think you need to specify the type of the props of the class you're returning from addImage:

export const addImage = <P extends object>(WrappedComponent: React.ComponentType<P>) => {
  return class extends React.Component<P> { // <- The "<P>" is the missing part

That should get rid of the warning in your screenshot. But thereafter Alejandro Garcia Anglada is correct with all his comments about how exactly to then use the HOC.

2
votes

In your case you will need to wrap your component in this way.

  1. Having a reference to the react component you want to wrap:
const Image = ({ item }) => <Img src={item} />
  1. Passing the reference to the HOC with the argument. As you can see in your code above, your HOC is expecting a argument P and that argument is the type of the props you are passing to Image
type Props = {
  item: string
}

addImage<Props>(Image)
1
votes

Try to declare P as an interface

import * as React from 'react';
import Dropzone from 'react-dropzone'

interface P extends Object {
    ...
}

export const addImage = (WrappedComponent: React.ComponentType<P>) => {
  return class extends React.Component {

    render() {

      return <Dropzone noClick onDrop={()=>{console.log('drop')}}>
        {({ getRootProps, getInputProps }) => (

        <div {...getRootProps()} onClick={()=>{console.log('aa')}}>
              <input {...getInputProps()} /> 
              <WrappedComponent {...this.props} />;
         </div>

        )}

      </Dropzone>

    }
  };
}
0
votes
export const addImage = <P extends object>(WrappedComponent: React.ComponentType<P & 
Props>, props: Props, ref) => {
  return class extends React.Component<P & Props, State> {
render() {
<input/>

...

How to add ref to input?