简体   繁体   中英

Correct way to cast a JSON object into a typescript typed variable using a class?

This is a more simple example of what I'm trying to do:

export class Person{
    id:Number;
    name:String;
}

export class PersonForm{

    // This line:
    default:Person = {name: "Guy"};
    // Gives the following error:
    //  Error:(25, 5) TS2322: Type '{ name: string; }' is not assignable to type 'Person'.
    //  Property 'id' is missing in type '{ name: string; }'.

    // I tried <Person>{name: "Guy"} but it gives the same error.

}

How can I make the compiler ignore this issue as long as Im not using non existant properties, or how do I declare the class so I can do the assignment this way instead of new Person() and then setting just the properties I want.

Note: Sending an object with all the properties into the constructor is not the solution I'm expecting. Also using an interface works because I can declare the fields optional, how can I do the same in a class?

Adding some more info:

The main goal of what I'm trying to achieve:

Find the best way to declare a class (not an interface) so I can initialize it with clean code in one line setting only the parameters I want to set. In Java you would overload constructors or use the Builder pattern.

I could certainly try the builder pattern but I'm looking for a more typescript way to do it, if there's any.

I found the easiest way to do it, and IT IS POSSIBLE. I think I had tried it this way before but the fact that I was using the "Number" & "String" types instead of "number" & "string", might be giving me missleading errors from the compiler, the following code works wonders for me:

export class Person{
    constructor(
        public id?: number, // make sure you use number and string types instead of Number and String types
        public name?: string // make sure you make all properties optional using "?"
    ){}
}

export class PersonForm{
    default:Person = <Person>{name: "Guy"};
}

You could write your class with a constructor.

export class Person {
  constructor(public id: number, public name: string) {}
}

But you would have to call it like this.

let person = new Person(null, "George");

Cast the JSON expression to any . The line to assign default becomes:

default: Person = <any>{ name: "Guy" };

This is another option to complement the other answers posted here..

If you have some object initialiser

{
  name:"John" 
}

and you explicitly want an instance of the class Person , but want keep the object initialiser, while keeping the defaults that the class Person creates, you can do it via passing the entire object into the class constructor:

var instance = new Person({name:"John"});

where

export class Person
{
   id:number = 0; //or generate one
   name:string = "unknown";
   constructor(opts:{id?:number; name?:string}){
      if(opts){
          this.id = opts.id || this.id;
          this.name = opts.name || this.name;
      }
   }
}

examples:

var people = [
   new Person(),
   new Person({name:"John"}),
   new Person({name:"James", id:10}),
   new Person({id:20})];

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