I have an item object that I collect from this custom hook (from React DnD). The problem is that typescript doesn't allow me to access its property in the drop function below, because its type is unknown.
function MyComponent(props){
const [{item}, drop] = useDrop({
accept: "BLOCK",
collect: monitor => ({
item: monitor.getItem() // Item object collected here IDropTargetMonitor
}),
drop: (): void => setBlock_name(item.block_name) // /!\ Object [item] is of type 'unknown'
})
return ...
}
The corresponding interface in the module is the following :
export interface DropTargetMonitor<DragObject = unknown, DropResult = unknown>
I define what I want in the item object here :
const OtherComponent = (props) => {
const [{isDragging}, drag] = useDrag({
type: "BLOCK",
item: {blockName: props.blockName}, // blockName is a string
collect: monitor => ({
isDragging: monitor.isDragging()
})
})
return ...
}
I would be grateful if someone could give me an hint on how I could infer the item type.
CodePudding user response:
There are some things that can be adjusted from your code. useDrop
is a generic that accepts the types for the dragged item. It's defined as:
useDrop<DragObject = unknown, DropResult = unknown, CollectedProps = unknown>
You could create an interface for your item:
interface Item {
blockName: string;
}
and then refactor your useDrop
hook like:
const [{item}, drop] = useDrop<Item, unknown, {item: Item}>({
accept: "BLOCK",
collect: monitor => ({
item: monitor.getItem()
}),
drop: (item: Item): void => setBlock_name(item.blockName)
})
This way Typescript will know that item
is of type Item
. A couple things to notice is that in your code you had setBlock_name(item.block_name)
but it should be setBlock_name(item.blockName)
since in your useDrag
you used item: {blockName: props.blockName}
so the property name is blockName
instead of block_name
. The other thing is that if you're gonna use the dropped item in your drop
method in useDrop
you should use the one that is passed as the first argument for drop: (item) => void
, you don't need to capture item in the collect
function. Hope this helps you.