Skip to main content

TypeScript Classes

TypeScript adds types and visibility modifiers to JavaScript classes.

This page assumes you already know how plain JavaScript classes work.


Members: Types

The members of a class — its properties and methods — get types with type annotations, just like variables.

Example

name: string declares a property that must hold text.

Prompt
Show that class properties are typed with annotations like variables. Declare a class Person with a name property typed string, create an instance and set its name to "Jane". The example prints nothing.
Output: TypeScript file and captured output

Members: Visibility

Class members can also carry special modifiers that control where they can be accessed from.

Note: There are three main visibility modifiers in TypeScript.

  • public — (default) the member can be accessed from anywhere
  • private — the member can only be accessed from inside the class
  • protected — the member can be accessed from the class itself and any class that inherits from it (see the inheritance sections below)

Note: Inside a class, the this keyword usually refers to the current instance of the class.

Example

Calling getName() is fine because the method is public. Reading person.name from outside the class is a compile error because name is private.

Prompt
Show the private and public visibility modifiers on class members. Declare a class Person with a private name: string, a public constructor that sets it, and a public getName() method; create a Person named "Jane", log getName() (allowed), then log person.name directly so the compiler reports that name is private and only accessible within the class.
Output: TypeScript file and captured output

Parameter Properties

TypeScript offers a shortcut for defining class members in the constructor: add a visibility modifier to the constructor parameter, and it becomes a member automatically.

Example

private name: string in the constructor both declares the name member and assigns it — no separate property line needed.

Prompt
Show parameter properties: declaring a class member directly in the constructor parameter list. Declare a class Person whose constructor takes private name: string (with an empty body), plus a public getName() method returning it; create a Person named "Jane" and log getName(), printing Jane.
Output: TypeScript file and captured output

Readonly

Like with arrays, the readonly keyword stops a class member from being changed after it is set.

Example

A readonly member must be given its value either where it is declared or in the constructor, and cannot change afterwards.

Prompt
Show the readonly modifier on a class property. Declare a class Person with a private readonly name: string set once in the constructor (with a comment explaining it cannot change afterwards) and a public getName() method; create a Person named "Jane" and log getName(), printing Jane.
Output: TypeScript file and captured output

Inheritance: Implements

An interface can describe the shape a class must follow. The class promises to match it with the implements keyword.

Note: A class can implement several interfaces by listing them after implements, separated by commas, like class Rectangle implements Shape, Colored {

Example

Rectangle must provide a getArea method because the Shape interface requires one.

Prompt
Show a class implementing an interface with the implements keyword. Declare an interface Shape with a getArea function property returning number, then a class Rectangle that implements it using protected readonly width and height parameter properties and a getArea() method returning width times height. The example only declares and prints nothing.
Output: TypeScript file and captured output

Inheritance: Extends

A class can build on another class with the extends keyword.

A class can only extend one other class.

Example

Square extends Rectangle, passes the same value for width and height to super, and inherits getArea without writing it again.

Prompt
Show class inheritance with the extends keyword. Declare a Shape interface and a Rectangle class implementing it (protected readonly width and height, getArea() returning their product), then a Square class extending Rectangle whose constructor takes one width and calls super(width, width), inheriting getArea. The example only declares and prints nothing.
Output: TypeScript file and captured output

Override

When a class extends another, it can replace members of the parent that have the same name.

Newer versions of TypeScript let you mark this explicitly with the override keyword.

Note: By default the override keyword is optional when overriding a method; it only helps catch mistakes, such as "overriding" a method that does not exist in the parent. Turn on the noImplicitOverride setting to require it.

Example

Square replaces the toString it inherited from Rectangle. The protected members are still accessible from Square.

Prompt
Show a subclass replacing a parent method, marked with the override keyword. Declare a Shape interface, a Rectangle class implementing it with protected readonly width and height, getArea() and a toString() returning "Rectangle[width=..., height=...]", then a Square subclass whose override toString() returns "Square[width=...]". The example only declares and prints nothing.
Output: TypeScript file and captured output

Abstract Classes

A class can be written so it only serves as a base for other classes, without implementing all of its members.

This is done with the abstract keyword on the class.

Members left without an implementation also use the abstract keyword.

Note: An abstract class cannot be instantiated directly, because not all of its members are implemented.

Example

Polygon leaves getArea abstract but implements toString using it. Rectangle extends Polygon and supplies the missing getArea.

Prompt
Show an abstract base class with an abstract method that subclasses must implement. Declare an abstract class Polygon with a public abstract getArea(): number and a concrete toString() returning "Polygon[area=...]", then a Rectangle class extending it with protected readonly width and height, calling super() and implementing getArea(). The example only declares and prints nothing.
Output: TypeScript file and captured output