TypeScript for Angular 2 - Part 4 (Classes and Interfaces)

Classes

After we learnt some amazing features of TypeScript static typing, we cannot leave class and interface behind, which is the most fundamental components in OO paradigm. We have already seen Classes and their declaration in TypeScript for Angular 2 - Part 2. The syntax used in TypeScript to define classes are similar to what ES2015 offers. So, we will skip to access modifier.

Access Modifier

TypeScript allows us not only to define class but also to control the access to the property of the class that we defined. The supported access modifiers by TypeScript are:

  1. Public: All the properties and methods could be accessed anywhere if they are declared as public.
  2. Private: Those, which are declared as private, can only be accessed within the class definition itself.
  3. Protected: When the properties and methods are declared as protected, they can be accessed from inside the class or any other class extending the one that owns the property or the method.

In order to clearly see how these access modifiers work, let's take a look at the following example, which is ported to TypeScript from ES2016 Classes Example 3 example that we used in TypeScript for Angular 2 - Part 2.

class Human {  
     static totalPeople = 0;
     constructor(protected name: string, private age: number) {
       Human.totalPeople += 1;
     }
     /* code */
}
class Developer extends Human {  
     constructor(name: string, private languages: string[], age: number){
       super(name, age);
     }
    /* code */
}

The constructor is completely optional in TypeScript classes. A default constructor that takes no parameters and initialises any instance members, will be automatically generated during the compile-time if there is no constructor is provided.

In this snippet, the access modifiers for properties: name, number and languages are defined directly inside the constructor function. Let's access these properties by creating new instances of the the classes.

let human = new Human("foo", 42);
human.age = 42;
human.name = "bar";

let dev = new Developer("foo", ["Python", "Java"], 26);
dev.languages = ["php"];

TypeScript will throw errors for the age and name with messages Property age is private and is only accessible inside class "Human" and the Property name is a protected and only accessible inside class "Human" and its subclasses. respectively for Human class. For Developer class, Property languages is private and only accessible inside class "Developer" will be shown for thelanguages property.

Interfaces

Interfaces are a key piece of creating large-scale software applications and they represent complex types about any object. Based on OO paradigm, TypeScript allows classes can optionally inherit type information from interfaces using the implements keyword. This means that our objects get similar behaviour if they implement interfaces that declare the subset of the properties they own.

We can define our interface Point as following:

interface Point {  
    x: number;
    y: number;
    getPoint() : number[];
}

Now, we can make sure the Point class implements Point interface by doing like:

class Point implements Point {  
    constructor(public x: number, public y = 0) {
    } 
    getPoint() : number[] {
        /* code */
   }
}

TypeScript interfaces support both properties and methods implementation: properties x and y, and getPoint() method in the preceding example. Both implemented properties and methods must have the same signature as the ones declared in the interface definition.

The class, which implements to an interface, needs to implement all of that interface members with the same signature; otherwise, compile-time errors will occur.

Interface inheritance

Interfaces have the ability to inherit from base types. This allows us to create a more enhanced version of interfaces by extending existing interfaces.

interface AddPointer {  
    add(arg1: number, ...args: number[]): number;
}

interface SubPointer {  
    subtract(arg1: number,  ...args: number[]): number;
}

interface MixPointer extends AddPoint, SubPoint {  
    multiply(arg1: number, ...args: number[]): number;
    square(arg1: number): number;
}

In this example, MixPonter is extending both AddPointer and SubPointer while it is defining two new methods that also performs mixing points functions itself, which are neither adding nor subtracting points. Then we can now reference these interfaces as type parameters or type declarations. We cannot instantiated interfaces and referred the members of an interface by using its type name directly.

This would be the end of TypeScript for Angular 2 posts and I hope you enjoy reading these posts. Actually, these 4 posts about TypeScript are like notes that I took from reading Switching to Angular 2 by Minko Gechev and TypeScript Essentials by Christopher Nance. I am here for just sharing what I learnt and making references for myself.

Thank you for reading and sharing would be my pleasure if you enjoy this post. Cheers.

Nay Win Myint

A JavaScript full-stack web developer, also interested in Android application development and Graphic design.

United Kingdom