2

I'm using React with Typescript and try to create a higher order component based on the react-dnd library. The error occurs in the DragSource part of the react-dnd component. This is the corresponding code:

import React from 'react';
import { DragSource, ConnectDragSource, DragSourceConnector, DragSourceMonitor } from 'react-dnd';
import ItemTypes from './itemTypes'

const collect = (connect: DragSourceConnector, monitor: DragSourceMonitor) => {
    return {
        connectDragSource: connect.dragSource(),
        isDragging: monitor.isDragging()
    }
}

const templateObjectSource = {
    beginDrag(props: any) {
        return {}
    }
}

export interface TemplateObjectCollectedProps {
    canDrop: boolean
    isOver: boolean
    connectDragSource: ConnectDragSource
}

export interface TemplateObjectProps {
    name?: string
}

function withTemplateObjectDraggable(WrappedComponent: React.ComponentClass<TemplateObjectProps>) {
    return class WithTemplateObjectDraggable extends React.Component<TemplateObjectCollectedProps> {
        public render() {
            return this.props.connectDragSource(
                <div>
                    <WrappedComponent {...this.props} />
                </div>
            )
        }
    }
}

export default DragSource(ItemTypes.TEXTFIELD, templateObjectSource, collect)(withTemplateObjectDraggable)

Typescript gives me the following error on the last line, specifically on the '(withTemplateObjectDraggable)' part:

[ts]
Argument of type '(WrappedComponent: ComponentClass<TemplateObjectProps, any>) => typeof WithTemplateObjectDraggable' is not assignable to parameter of type 'ComponentType<ComponentClass<TemplateObjectProps, any>>'.
Type '(WrappedComponent: ComponentClass<TemplateObjectProps, any>) => typeof WithTemplateObjectDraggable' is not assignable to type 'FunctionComponent<ComponentClass<TemplateObjectProps, any>>'.
Type 'typeof WithTemplateObjectDraggable' is not assignable to type 'ReactElement<any>'.
Property 'type' is missing in type 'typeof WithTemplateObjectDraggable'. [2345]

I'm not sure if I'm using the higher order component incorrectly or if it's just a type topic. Unfortunately I didn't find an example that combines react-dnd with additional higher order components so it may be that I'm on the wrong path. It would already help me if you could provide me a link to a working typescript (or javascript) example that implements a higher order component on top of "DragSource" in react-dnd as I couldn't find one.

FYI: I would then use the higher order component like this:

import React from 'react';
import imgTextfield from '../../../../../assets/templateObjects/textfield.png'
import withTemplateObjectDraggable from './withTemplateObjectDraggable'

class Textfield extends React.Component {
    public render() {
        return (
            <span>
                <img src={imgTextfield} />
                <div> Textfield </div>
            </span>
        )
    }
}

export default withTemplateObjectDraggable(Textfield)
microman
  • 141
  • 2
  • 12

1 Answers1

1

It seems you have your logic a bit wrong. DragSource expects a React component as an input, but you're trying to pass your withTemplateObjectDraggable HOC in. Hence Typescript complains about incompatible types.

I'm not 100% sure whether it will work or not, but try moving DragSource inside your HOC like so:

function withTemplateObjectDraggable(WrappedComponent: React.ComponentClass<TemplateObjectProps>) {
    class WithTemplateObjectDraggable extends React.Component<TemplateObjectCollectedProps> {
        public render() {
            return this.props.connectDragSource(
                <div>
                    <WrappedComponent {...this.props} />
                </div>,
            );
        }
    }

    return DragSource(ItemTypes.TEXTFIELD, templateObjectSource, collect)(WithTemplateObjectDraggable);
}
euvs
  • 1,595
  • 13
  • 13
  • Thank you a lot. That was the solution! You can't believe how long I was searching for that issue. Thanks!!! – microman Dec 17 '18 at 13:43