What is preventing me from being able to use object spread results in TypeScript casting?

Uniqueness in Question

My inquiry was not aimed at identifying the type or class name of an object. Rather, it delved into the concept of "casting" an object to a specific type, which arose from a misconception about TypeScript and its functionality. This query also pertained to utilizing Object spread while performing the casting process.

Distinctive Query

I aimed to utilize object spread to translate data received from the server into a client-defined class. My goal was to avoid manually passing data to a constructor and mapping each property through a loop, as demonstrated in a related query found here. The approach I attempted involved the following steps:

//Server Data
var data = [
   {id: 1, name: "Book 1", authorName: "Author 1", 
     steps: [
       {id: 1, name: "Step 1"},
       {id: 2, name: "Step 2"}
     ]},
   {id: 2, name: "Book 2", authorName: "Author 2",
     steps: [
       {id: 1, name: "Step 1"},
       {id: 3, name: "Step 3"}
     ]}
 ];

 interface IBook {
    id: number;
    name: string;
    authorName: string;
    steps:IStep[];
 }

 interface IStep {
    id: number;
    name: string;
    status: string;
    processing: boolean;
 }

 class Book implements IBook {
   id: number;
   name: string;
   authorName: string;
   steps : Step[] ;
 }

 class Step implements IStep {
    id: number;
    name: string;
    status: string = "unknown";
    processed: boolean = false;
 }

 var list : Book[] = data.map(bitem=> {
      var book = <Book>{ ...bitem, ...new Book() } as Book;
      console.log(book) //Displays 'object' instead of 'Book'
      var steps = bitem.steps.map(sitem => <Step>{ ...sitem, ...new Step() } as Step;);]
      book.steps = steps;
      return book;
 }

 console.log(typeof list[0]); //Expected 'Book' but received 'object'

I'm intrigued by why the casting to type Book results in an object rather than the expected type. Is there a straightforward method to achieve this, or should I resort to the constructor approach for such mapping endeavors?

Answer №1

Take a look at this piece of code. You have the ability to pass an object to the constructor and then generate an instance using the method below:

 class Book implements IBook {
   id: number;
   name: string;
   authorName: string;
   steps : Step[] ;
   constructor(params: IBook) {
     Object.assign(this, params);
   }
 }

 class Step implements IStep {
    id: number;
    name: string;
    status: string = "unknown";
    processing: boolean = false;
    constructor(params: IStep) {
      Object.assign(this, params);
    }
 }


var list : Book[] = data.map((bitem:any)=> {
      var book = new Book(bitem);
      console.log(book) //Displays 'object' instead of 'Book'
      var steps = bitem.steps.map(sitem => (new Step(sitem)));
      book.steps = steps;
      return book;
 });

Feel free to experiment with a live demo here

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

Encountering issues with saving information to MongoDB

I recently started working with the MERN stack and I am trying to save user information in MongoDB, which includes two string attributes: "name" and "role". However, I encountered an error in the browser console stating "Failed to load resource: Request t ...

Discovering the previously dropped value from a droppable div

Currently, I am developing a dynamic formula generator using jQuery's drag and drop functionality. Here is what I have accomplished so far: I have two lists: <ul id="head"> <li class="horizontal">Salary</li> <li class="h ...

importing files from Uploadcare using ngCordova MediaFile

I am facing an issue while attempting to upload a sound file from ngCordova's $cordovaCapture service to UploadCare. The `uploadcare.fileFrom('object')` function is failing with an 'upload' error even though I have set the public k ...

Encountering an issue with Vue JS axios request and filter: the function this.XX.filter is not operational

I am encountering challenges while trying to implement a basic search feature on a JSON file obtained through an API. Each component works independently: I can successfully retrieve data from the API, perform searches on non-API data, and even search cert ...

Attach onClick event when employing a higher order component

Just getting started with React and I have a question. After following some blog posts, I was able to create a page using higher order components and componentDidMount to fetch data from an API and display it. Everything works smoothly and the code looks ...

Exploring the World of Popper.js Modifiers

Within our React and Typescript application, we integrate the react-datepicker library, which utilizes popper.js. Attempting to configure PopperModifiers according to the example provided here: . Despite replicating the exact setup from the example, a typ ...

Does the message "The reference 'gridOptions' denotes a private component member in Angular" signify that I may not be adhering to recommended coding standards?

Utilizing ag-grid as a framework for grid development is my current approach. I have gone through a straightforward tutorial and here is the code I have so far: typography.component.html https://i.stack.imgur.com/XKjfY.png typography.component.ts i ...

Creating a specialized pathway with variable inputs within the URL

As a Node beginner, I am facing a challenge with an Express exercise on dynamic routes. The task at hand is to create a route that can accept dynamic arguments in the URL path and respond with a quote from the respective author. Here's a snippet of th ...

Is there an appropriate method in Vue/Nuxt for managing and altering component data without using lifecycle hooks?

Scenario: I am dealing with a component that showcases a datatable listing Applications. Upon clicking a row, it triggers the opening of another component with appropriately loaded fields (for new or edit). The Challenge: The component loads a reference t ...

Is there a way to utilize JSON parse for converting deeply nested keys from underscore to camelCase?

A JSON string containing an object is on my mind: const str = `[{"user_id":"561904e8-6e45-5012-a9d8-e2ff8761acf6","email_addr":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="caa0a3a6a5bc8aaca ...

Position an HTML canvas at the very top of the webpage

Can someone help me figure out how to align a canvas element to the very top (0, 0) of a webpage? I attempted using margin: 0; padding: 0px;, but it didn't work. There always seems to be some white space at the top that I can't eliminate. ...

Guide: Implementing service utilization within a controller using Express and Typescript

This specific piece of TypeScript code is causing me some trouble. I'm attempting to utilize a service to retrieve data from a database, but unfortunately, I keep encountering the following error message: Cannot read property 'populationService&a ...

Error: Trying to access the 'previous' property of an undefined value

I keep encountering an error with functions in firebase: TypeError: Cannot read property 'previous' of undefined at exports.sendNotifications.functions.database.ref.onWrite (/srv/index.js:5:19) at cloudFunction (/srv/node_modules/firebase-functi ...

The function to focus on this.$refs[("p" + index)] element is not available

I need help transforming a div into an input box when clicked, allowing me to edit the post inside a loop. Here is the button found on the post: <a @click="setFocusEdit(index)" v-if="isAuthor(post)" href="#" >Edit Me</a> And here is the spec ...

Exploring the realm of arrays in jQuery and JavaScript

Seeking assistance as a beginner in Javascript/jQuery, I am looking for guidance on the following challenge: I have created a basic form with 7 questions, each containing 3 radio buttons/answers (except for question 5 which has 8 possible choices). My goa ...

Remove properties that are not part of a specific Class

Is there a way to remove unnecessary properties from the Car class? class Car { wheels: number; model: string; } const obj = {wheels:4, model: 'foo', unwanted1: 'bar', unwantedn: 'kuk'}; const goodCar = filterUnwant ...

How can you make the table rows in jQuery scroll automatically while keeping the table header fixed in

Many solutions exist for making the header fixed and the table scrollable using code samples or plugins. However, my specific goal is to have the table data rows scroll automatically once they are loaded while keeping the header fixed in place. Is there a ...

I require fixed headers that no longer stick once reaching a specific point

I have a setup where the names and occupations of participants are displayed next to their artworks, and I've made it sticky so that as we scroll through the images, the names stay on the left. Now, I want the names to scroll out once the images for e ...

Is there a way for me to show "No data" when the json response in vue js is empty?

Is it possible to display a message like "No search results" when there is no data available? I am new to this and only have basic understanding. Can someone guide me on how to achieve this? Example of my JSON data when it's empty: { "status": true ...

What is the process for reverting variables back to their original values using pure Javascript?

I am working on developing a hangman game using vanilla javascript and I need some assistance with resetting the game after a player loses. Specifically, I would like to: 1. Reset the "guessRemain" variable. 2. Clear out the "guess" id so that none of the ...