Inheritance Basics

extends and super

A class can extends another class to reuse its properties and methods. The child constructor must call super(...) first. A child can override a method; the override keyword makes that explicit.

Example

class Product {
  constructor(public name: string, public price: number) {}

  label(): string {
    return `${this.name} - Rs. ${this.price}`;
  }
}

class DigitalProduct extends Product {
  constructor(name: string, price: number, public downloadSizeMb: number) {
    super(name, price);
  }

  override label(): string {
    return super.label() + ` (download ${this.downloadSizeMb} MB)`;
  }
}

const items: Product[] = [
  new Product("Headphones", 1999),
  new DigitalProduct("TypeScript eBook", 299, 12),
];
items.forEach((p) => console.log(p.label()));
console.log(items[1] instanceof Product);

Output

Headphones - Rs. 1999
TypeScript eBook - Rs. 299 (download 12 MB)
true

Classes Are Also Types

Example

A class name can be used as a type. Because typing is structural, any object with the same shape fits, even if it was not created with new.

class Point {
  constructor(public x: number, public y: number) {}
}

function distance(a: Point, b: Point): number {
  return Math.hypot(a.x - b.x, a.y - b.y);
}

console.log(distance(new Point(0, 0), { x: 3, y: 4 }));

Output

5

Practice

Exercise: Create a class BankAccount with a readonly accountNo, a balance, and methods deposit(amount) and withdraw(amount) that throws if the balance is too low.

Show answer
class BankAccount {
  constructor(public readonly accountNo: string, public balance = 0) {}

  deposit(amount: number): void {
    this.balance += amount;
  }

  withdraw(amount: number): void {
    if (amount > this.balance) throw new Error("Insufficient balance");
    this.balance -= amount;
  }
}

const acc = new BankAccount("SB-001", 1000);
acc.deposit(500);
acc.withdraw(300);
console.log(acc.balance); // 1200