Classes in TypeScript

This post is 4 years old. (Or older!) Code samples may not work, screenshots may be missing and links could be broken. Although some of the content may be relevant please take it with a pinch of salt.

Classes in TypeScript really extend JavaScript's (ES2015) class functionality. We get access to the same functionality but we of course can access a lot of additional, TypeScript specific features. The first and most obvious addition is that we can use types for class members and in member functions.

Let's take a look at an example where we can see how types are applied to a class in TypeScript:

class Person {
name: string;
constructor(name: string) {
this.name = name;
}

introduce(): void {
console.log(`Hello, I am ${this.name}!`);
}
}

const person = new Person('Adam');
person.introduce(); // Hello, I am Adam!

Astute readers may have already noticed that there's another difference between a simple ES2015 class and the above TypeScript class – that is, we need to specify a member first before we can assign values to it using the this keyword – that's why we have a member name specified in the first line of the class definition.

Inheritance

Inheritance works in the same way and we can use both the extend keyword and the super method call to create a child class and to invoke a method from the parent class respectively:

class Person {
name: string;
constructor(name: string) {
this.name = name;
}

introduce(): void {
console.log(`Hello, I am ${this.name}!`);
}
}

class SuperHero extends Person {
constructor(name: string) {
super(name);
}

introduce(): void {
console.log('Ssshhh, I am a superhero ...');
super.introduce();
}
}

const batman = new SuperHero('Burce');
batman.introduce();
// Ssshhh, I am a superhero ...
// Hello, I am Burce!

So far we haven't seen major differences, however with TypeScript we can also add modifiers for class members.

Public, private and protected

Other object-oriented programming languages have support for modifying class members to enable encapsulation (an OOP programming mechanism) and allow the class members to be either public (i.e. accessible by any class), private (i.e. accessible by the class where the member is created) and finally protected (i.e. only the current class and subclasses that derived from the class where the member is created can access it).

public

In TypeScript if we don't specify a modifier, public is assumed therefore these two class declarations with the name member are effectively the same:

class Person {
public name: string;
}

class Person {
name: string;
}

private

However, differences arise when we specify class members to be private or protected. If a member is declared to be private only the class where the member is created can access it, we cannot access it anywhere else:

class Person {
public name: string;
private dob: string;
constructor(name: string, dob: string) {
this.name = name;
this.dob = dob;
}
}

const dave = new Person('Dave', '01/12/1973');
console.log(dave.name); // Dave
console.log(dave.dob); // Property 'dob' is private and only accessible within class 'Person'.

protected

The protected keyword is slightly different, we still cannot access the property outside the class other than when the class is extended:

class Person {
public name: string;
protected dob: string;
constructor(name: string, dob: string) {
this.name = name;
this.dob = dob;
}
}

class SuperHero extends Person {
constructor(name: string, dob: string) {
super(name, dob);
}
}

const spiderman = new SuperHero('Peter', '10/22/1984');
console.log(spiderman.name); // Peter
console.log(spiderman.dob); // Property 'dob' is protected and only accessible within class 'Person' and its subclasses.

Please note that the protected keyword can also be applied to constructors so that a constructor function can only be called when we extend a class.