Anatomy of a class – constructors, properties, methods, getters, and setters

The following piece of code illustrates how a class could be. Please note that the class property members come first and then we include a constructor and several methods and property accessors. None of them features the reserved word function and all the members and methods are properly annotated with a type except constructor:

class Car {
private distanceRun: number = 0;
color: string;

constructor(public isHybrid: boolean, color: string = 'red') {
this.color = color;
}

getCasConsumsption(): string {
return this.ishybrid ? 'Very low' : 'Too high!';
}

drive(distance: number): void {
this.distanceRun += distance;
}

static honk(): string {
return 'HOOONK!';
}

get distance(): number {
return this.distanceRun;
}
}

This class layout will probably remind us of the component class we built back in Chapter 1, Creating Our Very First Component in Angular. Basically, the class statement wraps several elements that we can break down into:

  • Members: Any instance of the Car class will feature two properties - color typed as string, and distanceRun typed as a number and they will only be accessible from within the class itself. If we instance this class, distanceRun, or any other member or method marked as private, it won't be publicly exposed as part of the object API.
  • Constructor: The constructor function is executed right away when an instance of the class is created. Usually, we want to initialize the class members here, with the data provided in the constructor signature. We can also leverage the constructor signature itself to declare class members, as we did with the isHybrid property. To do so, we just need to prefix the constructor parameter with an access modifier such as private or public. Same as we saw when analyzing functions in the previous sections, we can define rest, optional, or default parameters as depicted in the previous example with the color argument, which fallbacks to red when it is not explicitly defined.
  • Methods: A method is a special kind of member that represents a function and therefore, can return, or not, a typed value. Basically, it is a function that becomes part of the object API. Methods can be private as well. In this case, they are basically used as helper functions within the internal scope of the class to achieve the functionalities required by other class members.
  • Static members: Members marked as static are associated with the class and not with the object instances of that class. This means that we can consume static members directly, without having to instantiate an object first. In fact, static members are not accessible from the object instances and thus, they cannot access other class members using this. These members are usually included in the class definition as helper or factory methods in order to provide a generic functionality not related to any specific object instance.
  • Property accessors: In ES5, we could define custom setters/getters in a very verbose way with Object.defineProperty. Now, things have become quite simpler. In order to create property accessors (usually pointing to internal private fields as in the example provided), we just need to prefix a typed method named as the property we want to expose with set (in order to make it writable) and get (in order to make it readable).

As a personal exercise, why don't you copy the preceding piece of code at the playground page (http://www.typescriptlang.org/Playground) and execute it? We can even see an instance object of the Car class in action by appending this snippet right after the class definition and running the code and inspecting the output in the browser's developer tools console:

var myCar = new Car(false);
console.log(myCar.color); // 'red'
// Public accessor returns distanceRun:
console.log(myCar.distance) // 0
myCar.drive(15);
console.log(myCar.distance); // 15 (0 + 15)
myCar.drive(21);
console.log(myCar.distance); // 36 (15 + 21)
// What's my carbon footprint according to my car type?
myCar.getGasConsumption(); // 'Too high!'
Car.honk(); // 'HOOONK!' no object instance required

We can even perform an additional test and append the following illegal statements to our code, where we attempt to access the private property distanceRun or even apply a value through the distance member, which does not have a getter.

console.log(myCar.distanceRun);
myCar.distance = 100;

Right after inserting these code statements in the playground text field, a red underline will remark that we are attempting to do something that is not correct. Nevertheless, we can carry on and transpile and run the code, since ES5 will honor these practices. All in all, if we attempt to run the tsc compiler on this file, the runtime will exit with the following error trace:

example_26.ts(21,7): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher
example_26.ts(29,13): error TS2341: Property 'distanceRun' is private and only accessible within class 'Car'
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset