简体   繁体   中英

Why can't I cast the results of an object spread with TypeScript?

Not A Duplicate

My question had nothing to do with trying to find the type nor the class name of an object. My question was about "casting" an object to a type -- which stemmed from a misunderstanding of TypeScript and how it worked. It also related to the use of Object spread while casting.

Original Question

I want to use object spread to map data from the server into a class defined on my client. I was trying to get away from having to pass data to a constructor and map each property with a loop as illustrated here . I tried the following:

//Data from server
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) //Shows 'object' not 'Book'
      var steps = bitem.steps.map(sitem => <Step>{ ...sitem, ...new Step() } as Step;);]
      book.steps = steps;
      return book;
 }

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

I'm curious why the cast to type Book yields an object instead? Is there an easy way to accomplish this or do I need to use the constructor method to accomplish this kind of mapping?

What about this code, you can pass an object to the constructor and create an instance of the same by below technique

 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) //Shows 'object' not 'Book'
      var steps = bitem.steps.map(sitem => (new Step(sitem)));
      book.steps = steps;
      retrun book;
 });

working sample here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM