How can arrays be formatted to correspond with the type/interface of an external component?

Currently, I am utilizing a treeview library in React that requires an array of NodeModule[] as input. The array I am passing to the tree component is being used in another component with different key names. To align the data structure with NodeModule[], I made some changes (refer to "thirdTreeData"), but encountered an error:

Error Message: 'Argument of type' '{ id: number; parent: number | null; text: string; }[] | undefined' is not assignable to parameter of type 'NodeModel[] | (() => NodeModel[])'.

This is how NodeModule[] is structured:

export declare type NodeModel<T = unknown> = {
 id: number | string;
 parent: number | string;
 text: string;
 };

To match the key names with NodeModule[], I modified the data like this (renamed parent_id to parent and name to text):

const thirdTreeData = secondTreeData?.map(tree => {
return { id: tree.id, parent: tree.parent_id,  text: tree.name };
 });

Upon hovering over thirdTreeData, I see this:

const thirdTreeData: {
id: number;
parent: number | null;
text: string;
 }[] | undefined

(*secondTreeData's type is - const secondTreeData: ITree[] | undefined )

How can I convert its type to NodeModule[] so that I can successfully pass thirdTreeData into the tree component like this?

const [treeData, setTreeData] = useState<NodeModel[]>(thirdTreeData);

The above setup gives me an error message. I have already attempted specifying : NodeModule[] in front of thirdTreeData without success :(

 const thirdTreeData :NodeModule[] = secondTreeData?.map(tree => 

I am relatively new to TypeScript, so any help is greatly appreciated!

Answer №1

After some thought, I finally had a breakthrough! In order to meet the requirements of having a NodeModel[], I found that passing in || 0 for 'parent' was necessary to ensure it is recognized as a number when tree.parent_id is null.

I also implemented a safeguard to prevent thirdTreeData from being assigned 'undefined' by using a ternary operator to provide an empty array if secondTreeData is undefined!

const thirdTreeData: NodeModel[] = secondTreeData
? secondTreeData.map(tree => {
  return {id: tree.id, parent: tree.parent_id || 0, text: tree.name};
})
: [];

Answer №2

It appears that the error message is indicating that the thirdTreeData does not meet the requirements of the NodeModel type. To resolve this, you can specify that the parent property should be either a number or null, and the id should be a number within the NodeModel type as shown in the code snippet below:

export declare type NodeModel<T = unknown> = {
     id: number; // <-- id must be a number
     parent: number | null; // <-- parent can be a number or null
     text: string;
};

Additionally, it is recommended to set the treeData state generic to be either NodeModel[] or undefined:

const [treeData, setTreeData] = useState<NodeModel[] | undefined>(thirdTreeData);

I hope this solution resolves the issue for you.

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

Using Cypress fixtures with TypeScript

After transitioning from using Cypress with Javascript specs to Typescript, I encountered a challenge in working with Fixtures. In Javascript, the approach below worked; however, I faced difficulties when switching to Typescript. Fixture JSON file: I sto ...

Angular: Clicking on a component triggers the reinitialization of all instances of that particular component

Imagine a page filled with project cards, each equipped with a favorite button. Clicking the button will mark the project as a favorite and change the icon accordingly. The issue arises when clicking on the favorite button causes all project cards to rese ...

Throw TypeError: The `pipe` property of `ngrx/store` is undefined during testing

Here is the code snippet from my TypeScript file: this.store.pipe(select(subscribe.getRegCategories)).pipe(takeUntil(this.ngUnsubscribe)).subscribe(data => { if (data && data.length) { this.allRegCategories = data; ...

Tips for incorporating Angular2 into Eclipse using TypeScript

Recently, I delved into the world of Angular 2 and noticed that TypeScript is highly recommended over JavaScript. Intrigued by this recommendation, I decided to make the switch as well. I came across a helpful guide for setting up everything in Eclipse - f ...

Create duplicates of both the array and its individual elements by value

I'm having trouble figuring out how to properly copy an array along with all its elements. In my model, I have a name and options, both of which are strings. This is what I currently have: const myArrayToDuplicate = [myModel, myModel, myModel] My ...

Ways to exit a loop in TypeScript

I've encountered an issue with the following code where I am struggling to break the loop under certain conditions. Desired Outcome: An error message should display, allowing the user to close it and remove the escalation node correctly. Actual Outc ...

What is the proper way to utilize a function in C# that integrates with a window form using TypeScript?

I am currently working on a code that is in c# and utilizes a web browser. My goal is to convert the existing JavaScript code to Angular 7 and Typescript. Below is the c# code and the corresponding JavaScript code used to access the c# function from JavaS ...

What is the correct approach for detecting object collisions in Phaser 3?

Hey everyone, I'm facing a problem and could use some assistance. Currently, I am trying to detect when two containers collide in my project. However, the issue is that the collision is being detected before the objects even start moving on screen. It ...

Cucumber Wrangler

I am completely new to using protractor/cucumber and restler in Typescript. The code below is what I have so far for hitting an endpoint URL and getting the response: Given('Hit the {string}', async (string) => { browser.quit() var data: ...

Is there a missing .fillGeometry in the Figma plugin VectorNode?

The documentation for VectorNode mentions a property called fillGeometry. Contrary to this, TypeScript indicates that "property 'fillGeometry' does not exist on type 'VectorNode'". https://i.sstatic.net/ICfdw.png I seem to be missing ...

Distinguishing SharePoint React Webpart from Office: A Comparison

My goal is to develop a client-side Webpart in React for SharePoint Online that utilizes OfficeJs to initiate a new email message on the user's Outlook desktop. However, I'm encountering a persistent "Office is not defined" error no matter what ...

Accessing information necessitates two separate subscriptions

I am posting this inquiry in order to enhance my understanding. Below is an excerpt from my service: export class HomeService { private generalstatistics = new ReplaySubject<object>(); constructor( private http: HttpClient ) { this ...

Is it possible to establish a specific many-to-many relationship using Prisma?

In the Prisma documentation, it states that the set function can be used to override the value of a relation. const user = await prisma.user.update({ where: { email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="73121f ...

Adding a Key Value pair to every object within an Array using TypeScript

I have two arrays - one contains dates and the other contains objects. My goal is to include the dates as a key value pair in each object, like this: {"Date": "10-12-18"}. dates: ["10-12-18", "10-13-18", 10-14-18"] data: [ {"name":"One", "age": "4"} ...

The Angular-Chart.js chart fails to display when data is automatically inserted

I came across this sample code at https://stackblitz.com/edit/angular-chartjs-multiple-charts and tried using it. Everything was working well with static data, but when I attempted to push data retrieved from the Firebase Realtime Database into the chart, ...

The server is not allowing the requested method through HTTP POST and therefore returning

Excuse me if this question sounds beginner or if my terminology is incorrect, because I am new to this. I have created a basic Python API for reading and writing to a database (CSV file) with Angular 5 as my front end. While I was able to successfully ret ...

Creating a customized Axios instance in Typescript can provide more flexibility and control over

I am looking to create an API with a customizable instance using Axios. Ideally, I want to be able to use a basic instance like this: api.get("url")... In addition, I would like to have the flexibility to add dynamic bodies and access them using something ...

JavaScript - Assigning the same value to 2 properties but console log displays them as distinct values

While iterating through an array of documents, I am encountering a strange issue where setting two properties to the same value results in them having different values when logged using console.log. Here is the code snippet: this.logicItem.$promise.then( ...

NextRouter does not have a property called "refresh"

Here is the provided code snippet: "use client"; import { useRouter } from "next/router"; import { useState } from "react"; export default function CreatePrompt() { const [title, setTitle] = useState(""); const ...

Retrieve highlighted text along with its corresponding tag in ReactJS

my <span class="highlight">highlighted</span> word The text above is showing an example including HTML tags. However, when using window.getSelection(), only the text "my highlighted word" is returned without the surrounding <span& ...