TSTypeScript · Lesson 5 of 10

Classes

TypeScript classes add access modifiers (`public`, `private`, `protected`, `readonly`) and parameter properties — a shorthand that declares and assigns instance properties in the constructor signature.

TypeScript
class Animal {
  // Access modifiers:
  // public    — accessible anywhere (default)
  // private   — accessible only inside this class
  // protected — accessible inside this class and subclasses
  // readonly  — can only be assigned in constructor

  readonly id: number
  public name: string
  private sound: string
  protected energy: number = 100

  // Static counter
  private static nextId = 1

  // Parameter properties — shorthand for declaring + assigning
  constructor(name: string, sound: string) {
    this.id    = Animal.nextId++
    this.name  = name
    this.sound = sound
  }

  speak(): string {
    return `${this.name} says ${this.sound}!`
  }

  // Getter / setter
  get isEnergetic(): boolean {
    return this.energy > 50
  }

  set energyLevel(val: number) {
    if (val < 0 || val > 100) throw new RangeError("Energy must be 0-100")
    this.energy = val
  }

  static kingdom = "Animalia"
}

const a = new Animal("Rex", "woof")
console.log(a.speak())          // Rex says woof!
console.log(a.isEnergetic)      // true
console.log(Animal.kingdom)     // Animalia
TypeScript
// Inheritance and abstract classes
abstract class Shape {
  abstract area(): number    // subclasses must implement
  abstract perimeter(): number

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

class Circle extends Shape {
  constructor(private radius: number) {   // parameter property shorthand
    super()
  }

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

class Rectangle extends Shape {
  constructor(
    private width: number,
    private height: number,
  ) { super() }

  area(): number      { return this.width * this.height }
  perimeter(): number { return 2 * (this.width + this.height) }
}

// Interfaces implemented by classes
interface Serializable {
  serialize(): string
  deserialize(data: string): void
}

class Config implements Serializable {
  private data: Record<string, unknown> = {}

  serialize(): string       { return JSON.stringify(this.data) }
  deserialize(json: string) { this.data = JSON.parse(json) }
  set(key: string, val: unknown) { this.data[key] = val }
  get(key: string) { return this.data[key] }
}

const c = new Circle(5)
const r = new Rectangle(4, 6)
console.log(c.describe())   // Area: 78.54, Perimeter: 31.42
console.log(r.describe())   // Area: 24.00, Perimeter: 20.00