React DnD组件中如何推断Item对象的TypeScript类型?
解决React DnD useDrop中item类型为unknown的问题
步骤1:定义统一的拖拽对象类型
先创建一个类型别名或接口,明确拖拽item的结构,确保拖拽和放置组件共用这个类型:
// 定义拖拽对象的类型 type BlockDragItem = { blockName: string; };
步骤2:在useDrag中指定泛型
在拖拽组件的useDrag钩子中,传入上面定义的类型作为泛型参数,让React DnD明确拖拽对象的类型:
const OtherComponent = (props: { blockName: string }) => { const [{isDragging}, drag] = useDrag<BlockDragItem>({ type: "BLOCK", item: {blockName: props.blockName}, collect: monitor => ({ isDragging: monitor.isDragging() }) }); return <div ref={drag}>...</div>; };
步骤3:在useDrop中指定相同泛型
在放置组件的useDrop钩子中,同样传入BlockDragItem作为泛型参数,这样DropTargetMonitor的getItem()方法就会返回正确的类型,而不是unknown:
function MyComponent(props) { const [blockName, setBlock_name] = useState<string>(""); const [{item}, drop] = useDrop<BlockDragItem>({ accept: "BLOCK", collect: (monitor: DropTargetMonitor<BlockDragItem>) => ({ item: monitor.getItem() // 此时item的类型为 BlockDragItem | undefined }), drop: () => { // 先判断item是否存在,因为getItem可能返回undefined if (item) { setBlock_name(item.blockName); } } }); return <div ref={drop}>...</div>; }
补充说明
- 必须确保
useDrag和useDrop的泛型类型一致,同时accept和type的字符串匹配(都是"BLOCK"),这样类型推断才会生效。 monitor.getItem()可能返回undefined(比如没有拖拽对象时),所以在使用item前最好做存在性检查,避免运行时错误。
内容的提问来源于stack exchange,提问作者loïc Torres
相关产品推荐
相关产品推荐

