Skip to content
intermediate Phase 3 · TypeScript Classes & Modules

Classes & Access Modifiers

Define classes with public, private, protected, and readonly modifiers.

1h
0 problems
Topic Progress 0%

Class Basics

Class Basics

Basic Class Definition

class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet(): string {
    return `Hi, I'm ${this.name}, ${this.age} years old.`;
  }
}

const alice = new Person('Alice', 30);
console.log(alice.greet());

Parameter Properties (Shorthand)

// Parameter properties auto-create and assign class members
class User {
  constructor(
    public readonly id: number,
    public name: string,
    private email: string,
    protected role: string = 'user'
  ) {}

  getDisplay(): string {
    return `${this.name} (${this.role})`;
  }
}

const user = new User(1, 'Alice', 'alice@test.com');
console.log(user.name);   // OK
// console.log(user.email); // Error: private

Access Modifiers

Modifier Class Subclass Outside
public Yes Yes Yes
protected Yes Yes No
private Yes No No
readonly Yes Yes (read) Yes (read)

Inheritance and Abstract Classes

Inheritance and Abstract Classes

Inheritance

class Animal {
  constructor(public name: string) {}

  speak(): string {
    return `${this.name} makes a sound.`;
  }
}

class Dog extends Animal {
  constructor(name: string, public breed: string) {
    super(name);
  }

  speak(): string {
    return `${this.name} barks!`;
  }
}

const rex = new Dog('Rex', 'Labrador');
console.log(rex.speak()); // 'Rex barks!'
console.log(rex.breed);   // 'Labrador'

Abstract Classes

abstract class Shape {
  abstract area(): number;
  abstract perimeter(): number;

  describe(): string {
    return `Area: ${this.area()}, Perimeter: ${this.perimeter()}`;
  }
}

class Circle extends Shape {
  constructor(public radius: number) {
    super();
  }

  area(): number {
    return Math.PI * this.radius ** 2;
  }

  perimeter(): number {
    return 2 * Math.PI * this.radius;
  }
}

// Cannot instantiate abstract class
// const shape = new Shape(); // Error
const circle = new Circle(5);
console.log(circle.describe());

Method Overriding

class Base {
  greet(): string {
    return 'Hello';
  }
}

class Derived extends Base {
  override greet(): string {
    return 'Hi there';
  }
}

// Use override keyword to prevent typos

Static Members

Static Members

Static Properties and Methods

class MathUtils {
  static readonly PI = 3.141592653589793;

  static add(a: number, b: number): number {
    return a + b;
  }

  static multiply(a: number, b: number): number {
    return a * b;
  }
}

MathUtils.PI;           // 3.141592653589793
MathUtils.add(1, 2);    // 3

// Static factory method
class User {
  constructor(
    public name: string,
    public email: string
  ) {}

  static fromJSON(json: string): User {
    const data = JSON.parse(json);
    return new User(data.name, data.email);
  }
}

const user = User.fromJSON('{"name":"Alice","email":"alice@test.com"}');

Static Initialization

class Config {
  static instance: Config;

  static {
    // Static initialization block
    Config.instance = new Config();
  }

  private constructor() {}
}

Enums as Static Collections

enum HttpMethod {
  GET = 'GET',
  POST = 'POST',
  PUT = 'PUT',
  DELETE = 'DELETE'
}

class ApiClient {
  static async request(method: HttpMethod, url: string): Promise<unknown> {
    const response = await fetch(url, { method });
    return response.json();
  }
}

ApiClient.request(HttpMethod.GET, '/api/users');

Getters and Setters

Getters and Setters

Computed Properties

class Temperature {
  private _celsius: number;

  constructor(celsius: number) {
    this._celsius = celsius;
  }

  get fahrenheit(): number {
    return this._celsius * 9 / 5 + 32;
  }

  set fahrenheit(value: number) {
    this._celsius = (value - 32) * 5 / 9;
  }

  get celsius(): number {
    return this._celsius;
  }

  set celsius(value: number) {
    if (value < -273.15) {
      throw new Error('Temperature below absolute zero');
    }
    this._celsius = value;
  }
}

const temp = new Temperature(100);
console.log(temp.fahrenheit); // 212
temp.fahrenheit = 32;
console.log(temp.celsius);    // 0

Validation in Setters

class BankAccount {
  private _balance: number = 0;

  get balance(): number {
    return this._balance;
  }

  set balance(value: number) {
    if (value < 0) {
      throw new Error('Balance cannot be negative');
    }
    this._balance = value;
  }

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

  withdraw(amount: number): boolean {
    if (amount > this._balance) return false;
    this.balance = this._balance - amount;
    return true;
  }
}