Property 'type' does not exist on type 'IntrinsicAttributes & DraggableProps', NEXTJS/ React
Answered
Petit Bleu de Gascogne posted this in #help-forum
Petit Bleu de GascogneOP
I'm using @hello-pangea/dnd (react-beautiful-dnd fork) to create a drag and drop list.
The thing is that, I'm using this custom prop
But, it doesn't exist on type 'IntrinsicAttributes & DraggableProps'.
Because of this error, I cannot build the app, but, what I've managed to do, is to add this into type
The app now builds, locally, but on Vercel, I still get that error.
What I've tried to do was, to add to github the path to the dnd types
I've managed to add it to repo, but, on vercel, it's downloading the package again, and I assume it's overlapping it.
Another thing I've tried was to create an interface that extends the props type, but it doesn't work...
I want to keep that type prop, because, I'm using the component twice for 2 separate things, and this allows me to track where do I do modifications.
The thing is that, I'm using this custom prop
<Draggable draggableId={section.id} index={index} type="section">
//type <- new/ custom propBut, it doesn't exist on type 'IntrinsicAttributes & DraggableProps'.
Because of this error, I cannot build the app, but, what I've managed to do, is to add this into type
type DraggableChildrenFn = (provided: DraggableProvided, snapshot: DraggableStateSnapshot, rubic: DraggableRubric) => ReactNode | null;
interface DraggableProps {
draggableId: DraggableId;
index: number;
children: DraggableChildrenFn;
isDragDisabled?: boolean;
disableInteractiveElementBlocking?: boolean;
shouldRespectForcePress?: boolean;
type?: string; <- this type
}The app now builds, locally, but on Vercel, I still get that error.
What I've tried to do was, to add to github the path to the dnd types
node_modules\.pnpm\@hello-pangea+dnd@16.6.0_@types+react-dom@18.2.24_@types+react@18.2.74_react-dom@18.2.0_react@18.2.0\node_modules\@hello-pangea\dnd\dist\dnd.d.tsI've managed to add it to repo, but, on vercel, it's downloading the package again, and I assume it's overlapping it.
Another thing I've tried was to create an interface that extends the props type, but it doesn't work...
I want to keep that type prop, because, I'm using the component twice for 2 separate things, and this allows me to track where do I do modifications.
if (type === "section") {
handleSectionDragDrop(source, destination, updatedSections);
} else {
handleTaskDragDrop(source, destination, updatedSections);
}Answered by Rafael Almeida
it is not very clean but instead of this:
you can do something like this:
then in your
<Droppable droppableId={section.id} type="task">you can do something like this:
<Droppable droppableId={`task|${section.id}`}>then in your
onDragEnd function you can read the type withconst type = result.droppableId.split('|')[0]28 Replies
Petit Bleu de GascogneOP
it's driving me crazy lol, i couldn't find any solutions.. please, anyone help me ;))
Petit Bleu de GascogneOP
up. anyone, please?
@Petit Bleu de Gascogne I'm using @hello-pangea/dnd (react-beautiful-dnd fork) to create a drag and drop list.
The thing is that, I'm using this custom prop
<Draggable draggableId={section.id} index={index} type="section">
//type <- new/ custom prop
But, it doesn't exist on type 'IntrinsicAttributes & DraggableProps'.
Because of this error, I cannot build the app, but, what I've managed to do, is to add this into type
type DraggableChildrenFn = (provided: DraggableProvided, snapshot: DraggableStateSnapshot, rubic: DraggableRubric) => ReactNode | null;
interface DraggableProps {
draggableId: DraggableId;
index: number;
children: DraggableChildrenFn;
isDragDisabled?: boolean;
disableInteractiveElementBlocking?: boolean;
shouldRespectForcePress?: boolean;
type?: string; <- this type
}
The app now builds, locally, but on Vercel, I still get that error.
What I've tried to do was, to add to github the path to the dnd types `
node_modules\.pnpm\@hello-pangea+dnd@16.6.0_@types+react-dom@18.2.24_@types+react@18.2.74_react-dom@18.2.0_react@18.2.0\node_modules\@hello-pangea\dnd\dist\dnd.d.ts
`
I've managed to add it to repo, but, on vercel, it's downloading the package again, and I assume it's overlapping it.
Another thing I've tried was to create an interface that extends the props type, but it doesn't work...
I want to keep that type prop, because, I'm using the component twice for 2 separate things, and this allows me to track where do I do modifications.
if (type === "section") {
handleSectionDragDrop(source, destination, updatedSections);
} else {
handleTaskDragDrop(source, destination, updatedSections);
}
yeah you can't edit a
I am not sure I understand how you are using this
node_modules package directly because you don't share the code between machines, you re-download everything so your change won't be thereI am not sure I understand how you are using this
type prop. you can't change the code of the component provided by the library so can you share a little more context about what you are trying to do? is this conditional code on type inside your own component?Petit Bleu de GascogneOP
So, I'm using the Draggable component Twice. One for "sections" one for "items". The sections can be reordered between them, items can be reordered between them and between sections. This is the code I'm using, to track what I'm moving, and where:
const onDragEnd = (result: DropResult) => {
const { source, destination, type } = result;
if (!destination) return;
const updatedSections = [...sections];
if (type === "section") {
handleSectionDragDrop(source, destination, updatedSections);
} else {
handleTaskDragDrop(source, destination, updatedSections);
}
};are you also modifying the code of the
Draggable component inside the node_modules folder to add the funcionality to this type prop? 🤔Petit Bleu de GascogneOP
well, not really. I'm not building the app now, and on dev, works fine, even tho I have errors. I modified package, yes, to test if the project builds, and it worked..
But after testing it out, I deleted the modification
yeah you will need to think about a alternative solution that does not involve modifying their package. technically you can patch the package code but it is a very brittle solution that can break any time they decide to update the code
Petit Bleu de GascogneOP
This is the entire code.. I couldn't do something better for now, to check the type of item I'm moving...
const onDragEnd = (result: DropResult) => {
const { source, destination, type } = result;
if (!destination) return;
const updatedSections = [...sections];
if (type === "section") {
handleSectionDragDrop(source, destination, updatedSections);
} else {
handleTaskDragDrop(source, destination, updatedSections);
}
};
const handleSectionDragDrop = (
source: any,
destination: any,
updatedSections: SectionType[]
) => {
const [removed] = updatedSections.splice(source.index, 1);
updatedSections.splice(destination.index, 0, removed);
const updatedWithPosition = updatedSections.map((section, index) => ({
...section,
position: index,
}));
setSections(updatedWithPosition);
updateSectionsOnServer(updatedWithPosition);
};
const handleTaskDragDrop = (
source: any,
destination: any,
updatedSections: SectionType[]
) => {
const sourceIndex = updatedSections.findIndex(
(section) => section.id === source.droppableId
);
const destIndex = updatedSections.findIndex(
(section) => section.id === destination.droppableId
);
if (source.droppableId === destination.droppableId) {
const updatedTasks = Array.from(updatedSections[sourceIndex].tasks);
const [removed] = updatedTasks.splice(source.index, 1);
updatedTasks.splice(destination.index, 0, removed);
updatedSections[sourceIndex].tasks = updatedTasks;
const updatedWithPosition = updatedTasks.map((task, index) => ({
...task,
position: index,
}));
setSections(updatedSections);
updateTaskOrder(updatedWithPosition);
} else {
const sourceTasks = Array.from(updatedSections[sourceIndex].tasks);
const destTasks = Array.from(updatedSections[destIndex].tasks);
const [removed] = sourceTasks.splice(source.index, 1);
destTasks.splice(destination.index, 0, removed);
updatedSections[sourceIndex].tasks = sourceTasks;
updatedSections[destIndex].tasks = destTasks;
setSections(updatedSections);
updateTaskSection(destTasks, source.droppableId, destination.droppableId);
}
};I mean, it works fine tho, but the app can't be built because of that error. I might try to get a workaround without modifying the package
where do you use this
onDragEnd function?Petit Bleu de GascogneOP
<DragDropContext onDragEnd={onDragEnd}>
<Droppable
droppableId="sections"
direction="horizontal"
type="section"
>
{(provided) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
className="flex"
>
{sections.map((section, index) => (
<Section key={section.id} section={section} index={index} />
))}
{provided.placeholder}
</div>
)}
</Droppable>and, on section component
<Draggable draggableId={section.id} index={index} type="section">
{(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
className={`m-1 min-w-xl w-72 hover:bg-gray-100/75 dark:hover:bg-neutral-700/25 transition-colors rounded-md ${
snapshot.isDragging ? "bg-gray-200/75 dark:bg-neutral-900/25" : ""
}`}
>
<div className="">
<div className="text-lg font-normal" {...provided.dragHandleProps}>
<div
className={`flex items-center justify-between gap-2 px-4 py-2 rounded-md transition-colors ${
!snapshot.isDragging
? "hover:bg-gray-300/50 dark:hover:bg-neutral-800/50"
: ""
}`}
>
<div className="flex items-center gap-2">
<div className="size-4 bg-red-600 rounded-full" />
{section.title}
</div>
</div>
</div>
<Droppable droppableId={section.id} type="task">
{(provided: DroppableProvided, snapshot) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
className={` ${
snapshot.isDraggingOver ? "bg-neutral-100/25" : ""
}`}
>
{section.tasks.map((task, index) => (
<Task key={task.id} task={task} index={index} />
))}
{provided.placeholder}
</div>
)}
</Droppable>
</div>
</div>
)}
</Draggable>then, i'm passing a type again, as you can see, here
<Droppable droppableId={section.id} type="task">
{(provided: DroppableProvided, snapshot) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
className={` ${
snapshot.isDraggingOver ? "bg-neutral-100/25" : ""
}`}
>
{section.tasks.map((task, index) => (
<Task key={task.id} task={task} index={index} />
))}
{provided.placeholder}
</div>
)}
</Droppable>so you only set the
onDragEnd once but you have multiple Draggable components nested with different types 🤔Petit Bleu de GascogneOP
Yeah, because I have DragDropContext only once
Now that you say this, I might modify it, to have it twice.. one for sections, one for items/ tasks
Well, I'm going to try again to find a workaround for what i have now, and if nothing works, might try to create dragdropcontext twice
it doesn't look like a trivial problem actually 

I read a bit of the documentation of the library and the only solution that I thought would be using the
droppableId as a way to recognize the origin of the drag eventit is not very clean but instead of this:
you can do something like this:
then in your
<Droppable droppableId={section.id} type="task">you can do something like this:
<Droppable droppableId={`task|${section.id}`}>then in your
onDragEnd function you can read the type withconst type = result.droppableId.split('|')[0]Answer
Petit Bleu de GascogneOP
The docs for react-beautiful-dnd is pretty vague.. they provide a type for Droppable, but not for Draggable...
@Rafael Almeida it is not very clean but instead of this:
js
<Droppable droppableId={section.id} type="task">
you can do something like this:
js
<Droppable droppableId={`task|${section.id}`}>
then in your `onDragEnd` function you can read the type with
js
const type = result.droppableId.split('|')[0]
Petit Bleu de GascogneOP
This might be a solution, I'm giving a try rn
Petit Bleu de GascogneOP
well, that's interesting.. I'm missing something out.. I removed the types from Draggable, and logged the onDragEnd, the type
And, apparently, it logs the correct type...
const onDragEnd = (result: DropResult) => {
const { source, destination, type } = result;
if (!destination) return;
const updatedSections = [...sections];
console.log(type);
};And, apparently, it logs the correct type...
So, my guess is that, the Draggable
type prop was useless, and it's getting that prop from Droppable (since there, type can be passed as a prop)@Petit Bleu de Gascogne So, my guess is that, the Draggable `type` prop was useless, and it's getting that prop from Droppable (since there, `type` can be passed as a prop)
this dnd library uses the
you have a Droppable component where you have a list of users, so you set the
now you have a third Droppable component for idk, fruits. you don't want to let the user drop users on the list of fruits so for this Droppable you set the type to
the type of the Draggable always inherits from the Droppable so you don't mix different types of items in the wrong list
type prop to limit where you can drop stuff, it makes sense that it is not available for Draggable:you have a Droppable component where you have a list of users, so you set the
type to USERS. then on the other list of users you also set it to USERSnow you have a third Droppable component for idk, fruits. you don't want to let the user drop users on the list of fruits so for this Droppable you set the type to
FRUITSthe type of the Draggable always inherits from the Droppable so you don't mix different types of items in the wrong list
Petit Bleu de GascogneOP
It works. It deploys to vercel successfully. Thank you!!!