Class in TypeScript

If you’re coming from JavaScript or just beginning with TypeScript, you might be wondering: What exactly is a class in TypeScript? More importantly, how do classes enhance your ability to build scalable, maintainable applications?

This guide is for learners, professionals, and developers who want a practical, complete, and well-explained introduction to TypeScript classes. By the end, you'll be able to define, instantiate, extend, and effectively use classes in your own projects.

What is a Class in TypeScript?

A class in TypeScript is a blueprint for creating objects with predefined properties and behaviors. If you've worked with JavaScript ES6, TypeScript classes build on that syntax but with added features like static typing, access modifiers, and interfaces for better code reliability.

Think of a class as a reusable template—just like a mold for casting metal. You define it once, then use it to create many consistent objects.

Why Use Classes in TypeScript?

  • Enforces type safety (compile-time checks).
  • Encourages object-oriented programming (OOP) principles.
  • Makes code modular, reusable, and maintainable.
  • Supports encapsulation, inheritance, and polymorphism.
  • Enables better IDE support with autocompletion and suggestions.

Creating a Basic Class

Here's how you define and use a class in TypeScript:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Animal {
  name: string;

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

  speak(): void {
    console.log(`${this.name} makes a sound.`);
  }
}

const dog = new Animal("Buddy");
dog.speak(); // Buddy makes a sound.

Breakdown:

  • class Animal — Declares the class.
  • name: string — A typed property.
  • constructor() — A special method that runs when a new object is created.
  • this.name = name — Assigns the input to the class property.
  • speak() — A method that logs output.

Adding Type Annotations

One of the biggest benefits of using TypeScript is adding types to your properties and methods:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
class Rectangle {
  width: number;
  height: number;

  constructor(width: number, height: number) {
    this.width = width;
    this.height = height;
  }

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

Here, we’ve explicitly stated that width and height are numbers, and the area method returns a number.

Access Modifiers: public, private, and protected

TypeScript classes support access control:

  • public (default): accessible everywhere.
  • private: accessible only within the class.
  • protected: accessible within the class and subclasses.

Example:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class BankAccount {
  private balance: number;

  constructor(initialBalance: number) {
    this.balance = initialBalance;
  }

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

  getBalance(): number {
    return this.balance;
  }
}

const account = new BankAccount(1000);
account.deposit(500);
console.log(account.getBalance()); // 1500
// account.balance = 0; // ❌ Error: 'balance' is private

Using private prevents unwanted access and modification from outside the class.

Getters and Setters

Getters and setters help control how properties are accessed or modified:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Person {
  private _age: number;

  constructor(age: number) {
    this._age = age;
  }

  get age(): number {
    return this._age;
  }

  set age(value: number) {
    if (value > 0) {
      this._age = value;
    }
  }
}

const john = new Person(25);
console.log(john.age); // 25
john.age = 30;
console.log(john.age); // 30

Readonly Properties

A readonly property can only be assigned once—either at declaration or inside the constructor.

typescript
1
2
3
4
5
6
7
8
9
10
class Vehicle {
  readonly brand: string;

  constructor(brand: string) {
    this.brand = brand;
  }
}

const car = new Vehicle("Toyota");
// car.brand = "Honda"; // ❌ Error: Cannot assign to 'brand'

Static Properties and Methods

Static members belong to the class itself, not instances:

typescript
1
2
3
4
5
6
7
8
9
class MathUtil {
  static PI = 3.14;

  static calculateCircumference(radius: number): number {
    return 2 * MathUtil.PI * radius;
  }
}

console.log(MathUtil.calculateCircumference(10)); // 62.8

Use static members when behavior or data is common to all instances.

Inheritance: Extending Another Class

One class can inherit from another using extends. This promotes code reuse and scalability.

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Animal {
  constructor(public name: string) {}

  speak(): void {
    console.log(`${this.name} makes a sound.`);
  }
}

class Dog extends Animal {
  bark(): void {
    console.log(`${this.name} barks.`);
  }
}

const dog = new Dog("Max");
dog.speak(); // Max makes a sound.
dog.bark();  // Max barks.

Implementing Interfaces

Interfaces define a contract for the structure of your class. This helps with consistency and abstraction.

tsx
1
2
3
4
5
6
7
8
9
10
11
interface Shape {
  area(): number;
}

class Circle implements Shape {
  constructor(private radius: number) {}

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

Abstract Classes

An abstract class can't be instantiated directly. It provides a partial blueprint that subclasses must complete.

typescript
1
2
3
4
5
6
7
8
9
10
11
abstract class Employee {
  constructor(public name: string) {}

  abstract getSalary(): number;
}

class FullTimeEmployee extends Employee {
  getSalary(): number {
    return 50000;
  }
}

Final Thoughts

TypeScript classes make your code easier to maintain, safer to work with, and better organized. With features like strong typing, access control, and interfaces, you can confidently build robust applications.

Whether you’re building a game, web app, or data model, mastering classes will elevate your TypeScript development skills.

Frequently Asked Questions