Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shorthand for field initializer when class has computed property

Let's say I have a very simple class with a calculated property:

class Person {
  firstName: string;
  lastName: string;

  get fuillName(): string {
    return this.firstName + ' ' + this.lastName;
  }
}

Now I want to create an object of type Person:

let p: Person = {
  firstName: 'John',
  lastName: 'Smith'
};

This gives me an error:

Type '{ firstName: string; lastName: string; }' is not assignable to type 'Person'. Property 'fuillName' is missing in type '{ firstName: string; lastName: string; }'.

Huh? fullName is a read-only property. So I followed this question and implemented a partial initializer:

constructor(init?: Partial<Person>) {
  Object.assign(this, init);
}

Same error. I know I can do this:

let p = new Person();
p.firstName = 'John';
p.lastName = 'Smith';
console.debug(p.fullName);

But is there a shorthand to initialize the class using the JSON syntax?

like image 696
Mike Henderson Avatar asked Sep 03 '17 18:09

Mike Henderson


1 Answers

If you define Person class as follows:

  class Person {
    firstName?: string;
    lastName?: string;

    constructor(values: Object = {}) {
      Object.assign(this, values);
    }

    get fullName(): string {
       return this.firstName + ' ' + this.lastName;
    }
  }

you can initialise a new user as the following:

  let p = new Person({firstName : 'John', lastName: 'Smith'}); //one line, two assignations
  console.log(p.fullName); 

To go further:

  class Person {
     ....// as above
     set fullName(fullName: string){
         let splitName = fullName.split(" ");
         this.firstName = splitName[0] || '';
         this.lastName = splitName[1] || '';
     }
   }

   let p = new Person()
   p.fullName = "Paul Doe";

Plunker Demo

like image 51
Vega Avatar answered Nov 12 '22 02:11

Vega