What is the method for determining the type in this component configuration?

When working with a custom hook from React DnD, I encounter an issue where TypeScript restricts my access to the property of an item object in the drop function due to its unknown type.

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 module's corresponding interface is as follows :

export interface DropTargetMonitor<DragObject = unknown, DropResult = unknown>

I specify the contents of the item object in this section :


const OtherComponent = (props) => {

    const [{isDragging}, drag] = useDrag({
        type: "BLOCK",
        item: {blockName: props.blockName}, // blockName is a string
        collect: monitor => ({
            isDragging: monitor.isDragging()
        })
    })

    return ...
}

If anyone has any ideas on how I can infer the item type, I would greatly appreciate the assistance.

Answer №1

Adjustments can be made to the code provided. The useDrop function is a generic that specifies the types for the dragged item. Here is how it's defined:

 useDrop<DragObject = unknown, DropResult = unknown, CollectedProps = unknown>

An interface can be created for the item like this:

interface Item {
  blockName: string;
}

The useDrop hook can then be refactored as follows:

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 recognize that item is of type Item. It's worth noting that in the original code there was setBlock_name(item.block_name), but it should actually be setBlock_name(item.blockName) since

item: {blockName: props.blockName}
was used in the useDrag function, meaning the property name is blockName not block_name. Additionally, if you plan on using the dropped item in the drop method within useDrop, you should utilize the item passed as the first argument in drop: (item) => void; there's no need to capture it in the collect function. I hope this explanation helps!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Extending State Interface in ReactJs and Typescript: A Step-by-Step Guide

I have the following: interface EditViewState<T> { entity?: T; } abstract class EditView<T, P, S> extends React.Component<P, EditViewState<T> & S> { constructor(props: P, ctx: any) { super(props, ctx); this. ...

What causes an array to accumulate duplicate objects when they are added in a loop?

I am currently developing a calendar application using ExpressJS and TypeScript. Within this project, I have implemented a function that manages recurring events and returns an array of events for a specific month upon request. let response: TEventResponse ...

How to handle a Node.js promise that times out if execution is not finished within a specified timeframe

return await new Promise(function (resolve, reject) { //some work goes here resolve(true) }); Using Delayed Timeout return await new Promise(function (resolve, reject) { //some work goes here setTimeout(function() { resolve(true); }, 5000); } ...

TypeScript enables the use of optional arguments through method overloading

Within my class, I have defined a method like so: lock(key: string, opts: any, cb?: LMClientLockCallBack): void; When a user calls it with all arguments: lock('foo', null, (err,val) => { }); The typings are correct. However, if they skip ...

Is there a way to incorporate several select choices using specific HTML?

I am currently trying to dynamically populate a select tag with multiple option tags based on custom HTML content. While I understand how to insert dynamic content with ng-content, my challenge lies in separating the dynamic content and wrapping it in mat ...

When using Router.push() in next.js, the error TypeError: products.map is not a function may arise

Currently, I am implementing redux saga in my project. Here is how the state looks: const productList = useSelector((state: RootState) => state.productList); const { loading, error, products, page, pages } = productList; In the useEffect hook, I dispa ...

The Typescript counterpart to PropTypes.oneOf, utilizing a pre-existing variable

While I know this question has been addressed on Stack Overflow here, I still find myself struggling with a similar issue in my TypeScript project. Currently, I am in the process of converting a JavaScript project to Typescript. Within one of my React com ...

What is causing the failure of the state to be inherited by the child component in this scenario (TypeScript/React/SPFX)?

For this scenario, I have a Parent class component called Dibf and a Child class component named Header. While I can successfully pass props from the Parent to the child, I am encountering difficulties when trying to pass state down by implementing the fo ...

What are the steps to update your profile picture using Angular?

In my Angular 6 application, I am implementing an image upload feature with the following code: Html: <img [src]="url ? url : 'https://www.w3schools.com/howto/img_avatar.png'"> <br/> <input type='file' (change)="onSelec ...

Displaying data from multiple checkboxes in an Angular application using an array

I'm currently facing an issue with displaying checked data in an Array within my Angular application. Upon clicking the checkbox, I receive a true value, but unfortunately, the data does not display as it contains null values. For reference, here is ...

Guide for exporting and overloading function argument lists with tuples of varying lengths in Typescript

Unfortunately, I am facing an issue with Typescript 4.5.4 where the following overload with different tuples of varying lengths does not seem to work for me: export function f<T1> (t: [T1]) : any { ... } export function f<T1,T2> (t: [T1,T2 ...

Using `new Date(device.timestamp).toLocaleString()` in React with typescript results in an invalid date

The timestamp I am receiving is in unix time format. {devices.map((device, index) => { return ( <tr key={index} className="bg-white border-b "> <td className="py-4 px-6"> {getSensor ...

Getting js.map Files to Function Properly with UMD Modules

I am experiencing an issue with debugging TypeScript files in Chrome and Firefox. Specifically, when trying to debug the MapModuleTest.ts file, the debugger seems to be out of sync with the actual JavaScript code by two lines. This discrepancy makes settin ...

Error with SwitchMap on ActivatedRoute.paramMap

When I try to run the ngOnInit method of my component, I encountered an error with the following line of code. this.products$ = this.route.paramMap.switchMap((params: ParamMap) => this.getProductsForType(params.get('type'))); The error mes ...

Google's reCAPTCHA issue: systemjs not found

Currently, I am attempting to integrate Google's reCAPTCHA into an Angular application by following a helpful tutorial found here. However, I have encountered a problem as the systemjs.config.js file seems to be missing from my Angular CLI project. An ...

Automatic browser refresh with the `bun dev` command

Currently experimenting with the latest bun platform (v0.1.6) in conjunction with Hono. Here are the steps I followed: bun create hono test-api cd test-api bun dev After running the server, the following message appears: $ bun dev [1.00ms] bun!! v0.1.6 ...

Using Vue.js, learn how to target a specific clicked component and update its state accordingly

One of the challenges I'm facing is with a dropdown component that is used multiple times on a single page. Each dropdown contains various options, allowing users to select more than one option at a time. The issue arises when the page refreshes afte ...

Tips for accessing other environment variables within the environment.ts file in an Angular project

Currently, I am working on modifying the 'environment.ts' file within an Angular project to include additional properties. The current setup looks like this: export const environment = { production: false, apiUrl: 'http://example.com&ap ...

Dynamic addition of script to <head> element in Angular is a common task for many developers

I have explored some examples that illustrate how to dynamically add a script with a URL in Angular However, I am interested in adding this type of content to the <head> <script> !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(! ...

Challenges faced when incorporating ng-content within Angular components

I am facing a specific issue where I need to pass code from a file containing a component to its child component. My initial approach was to use ng-content, but unfortunately, this method did not work as expected. I am unsure if the ng-content usage is inc ...