Sep 30, 2020

Class field initialization in typescript

In typescript class, you can define your field initialization in multiple ways. Here is one typical way to do that.

class BadPerson {

  fullName: string;
  age: number;
  created: Date;

  constructor(public firstName: string, public lastName: string) {
    this.fullName = this.firstName + ',' + this.lastName;
    this.age = 18;
    this.created = new Date();
    //
    //other imperative initailization goes to bottom
  }
}

//typescript will compile to javascript like 
class BadPerson {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.fullName = this.firstName + ',' + this.lastName;
        this.age = 18;
        this.created = new Date();
        //
        //other imperative initailization goes to bottom
    }
}

The problem here is that you have to explicitly have specify the types of each field, and you initialize them in different place from where they are declared. The better way to initialize class fileds is like the following.

class GoodPerson {

  fullName = this.firstName + ',' + this.lastName;
  age = 18;
  created = new Date();

  constructor(public firstName: string, public lastName: string) {
    //
    //other imperative initailization goes to bottom
  }
}
  
// typescript will compile to javascript like
class GoodPerson {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.fullName = this.firstName + ',' + this.lastName;
        this.age = 18;
        this.created = new Date();
        //
        //other imperative initailization goes to bottom
    }
}

Now the types of each fields are inferred correctly from the initialization, and you don't need to waste time to declare types from them. Secondly, you put initiaization and declaration in the same place, so the readability is much improved. Thirdly, the generated code is identical, so the logics is the same. It is true that field initialization happen before the code inside class constructor (from the code you can see that). So people believe that the shortcut field initialization in the constructor parameter is also initialized after normal field initialization, so if field initialization depends on the constructor parameter, they are not accessible. So people think they need to initialize those field inside the constructor. But from the compiled code, we can see that shortcut field initialization happens first, and they are accessible to other field initialization.

No comments:

Post a Comment