Search code examples
reactjstypescriptdefinitelytyped

Typescript React HOC error with hoist-non-react-statics


I'm using react and typescript and hoist-non-react-statics and trying to create a HOC. I've simplified the code to just a contrived HOC that wraps the component with a div.

const withWrapper = <TProps extends {}>(
  WrappedComponent: React.ComponentType<TProps>,
) => {
  const WithWrapper: React.FC<TProps> = (props: TProps) => (
    <div>
      <WrappedComponent {...props} />
    </div>
  )

  WithWrapper.displayName = `WithWrapper(${
    WrappedComponent.displayName || WrappedComponent.name || 'Component'
  })`

  return hoistNonReactStatics(WithWrapper, WrappedComponent)
}

But getting the error:

Argument of type 'ComponentType<TProps>' is not assignable to parameter of type 'ComponentType<any>'.
  Type 'ComponentClass<TProps, any>' is not assignable to type 'ComponentType<any>'.
    Type 'ComponentClass<TProps, any>' is not assignable to type 'FunctionComponent<any>'.
      Type 'ComponentClass<TProps, any>' provides no match for the signature '(props: any, context?: any): ReactElement<any, string | ((props: any) => ReactElement<any, string | any | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | null'.

     return hoistNonReactStatics(WithWrapper, WrappedComponent)
                                              ~~~~~~~~~~~~~~~~

Why is this invalid? The only way to get it to pass is by casting WrappedComponent as React.ComponentType<any>.

EDIT: [email protected] @types/[email protected] @types/[email protected]


Solution

  • Your code works fine with [email protected], @types/[email protected] and @types/[email protected].

    The only incorrect thing in your code is using a single pipe (|) instead of double one. A single pipe is used for bitwise OR, whereas double does short-circuiting — I believe you meant the latter.