Skip to content

Classes

class Pet {
  name: string; // property.
}

const pet = new Pet();
pet.name = "Mittens";

console.log(pet); // returns Pet { name: 'Mittens' }.

Member properties can be public, private, or protected.

  • Public members are accessible from anywhere (default).
  • Private members are only accessible from within the class.
  • Protected members are accessible from within the class and from classes that extend from the class.
class Pet {
  private name: string;

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

  public getName(): string {
    return this.name;
  }
}

const pet = new Pet("Snuggles");

console.log(pet.getName()); // since pet.name is private,
// it isn't accessible outside the class.

Shorthand: add a visibility modifier to constructor parameters to auto-create and assign properties.

class Pet {
  public constructor(private name: string) {}
  // name is a private member variable
  public getName(): string {
    return this.name;
  }
}

const pet = new Pet("Snowball");
console.log(pet.getName()); // logs 'Snowball'

Prevents class members from being changed.

class Pet {
  private readonly name: string;

  public constructor(name: string) {
    // name cannot be changed after definition,
    // which must be at it's declaration or in the constructor.
    this.name = name;
  }

  public getName(): string {
    return this.name;
  }
}

const pet = new Pet("Jingles");
console.log(pet.getName());

The implements key word is used to indicate that a class implements an interface to define the type a class must conform to.

interface Shape {
  getArea: () => number;
}

class Rectangle implements Shape {
  public constructor(
    protected readonly width: number,
    protected readonly height: number,
  ) {}

  public getArea(): number {
    return this.width * this.height;
  }
}

const ourRectangle = new Rectangle(11, 22);

console.log(ourRectangle.getArea());

Classes can implement multiple interfaces.

Inheritance - extends (extends Rectangle above)

Section titled “Inheritance - extends (extends Rectangle above)”

A class can extend another class to inherit its members. A class can only extend one other class.

interface Shape {
  getArea: () => number;
}

class Rectangle implements Shape {
  public constructor(
    protected readonly width: number,
    protected readonly height: number,
  ) {}

  public getArea(): number {
    return this.width * this.height;
  }
}

class Square extends Rectangle {
  public constructor(width: number) {
    super(width, width);
  }
  // inherited from Rectangle.
}

const ourSquare = new Square(22);

console.log(ourSquare.getArea());

When you use a class to extend another, you can override methods from the parent class by redefining them in the child class. You can also override properties.

interface Shape {
  getArea: () => number;
}

class Rectangle implements Shape {
  // using protected for these members allows access from classes that extend from this class, such as Square
  public constructor(
    protected readonly width: number,
    protected readonly height: number,
  ) {}

  public getArea(): number {
    return this.width * this.height;
  }

  public toString(): string {
    return `Rectangle[width=${this.width}, height=${this.height}]`;
  }
}

class Square extends Rectangle {
  public constructor(width: number) {
    super(width, width);
  }

  // Replaces earlier toString from Rectangle
  public override toString(): string {
    return `Square[width=${this.width}]`;
  }
}

const ourSquare = new Square(22);

console.log(ourSquare.toString());

Override keyword is optional, but it’s good practice to use it.

Can be used as a base for other classes, without having to implement or use all that classes members.

abstract class Polygon {
  public abstract getArea(): number;

  public toString(): string {
    return `Polygon[area=${this.getArea()}]`;
  }
}

class Rectangle extends Polygon {
  public constructor(
    protected readonly width: number,
    protected readonly height: number,
  ) {
    super();
  }

  public getArea(): number {
    return this.width * this.height;
  }
}

const ourRectangle = new Rectangle(10, 20);

console.log(ourRectangle.getArea());