classes and oop
Classes in TypeScript
TypeScript builds on JavaScript's class syntax by adding type annotations, access modifiers, and stricter structure — making object-oriented code safer and easier to maintain.
Defining a Class
class Car {
brand: string;
color: string;
speed: number;
constructor(brand: string, color: string) {
this.brand = brand;
this.color = color;
this.speed = 0;
}
accelerate(): void {
this.speed += 10;
console.log(`${this.brand} is now going ${this.speed} km/h`);
}
}
const myCar = new Car("Toyota", "Red");
myCar.accelerate(); // Toyota is now going 10 km/hAccess Modifiers
TypeScript adds three access modifiers to control how properties and methods can be used from outside the class.
| Modifier | Meaning |
|---|---|
public | Accessible from anywhere (the default if omitted) |
private | Accessible only from within the same class |
protected | Accessible within the class and its subclasses |
class BankAccount {
private balance: number;
constructor(initialBalance: number) {
this.balance = initialBalance;
}
deposit(amount: number): void {
this.balance += amount;
}
getBalance(): number {
return this.balance;
}
}
const account = new BankAccount(100);
account.deposit(50);
console.log(account.getBalance()); // 150
console.log(account.balance); // Error: Property 'balance' is privateShorthand Constructor Properties
TypeScript offers a shortcut: adding an access modifier directly to a constructor parameter automatically creates and assigns the matching property.
class BankAccount {
constructor(private balance: number) {}
getBalance(): number {
return this.balance;
}
}
const acc = new BankAccount(200);
console.log(acc.getBalance()); // 200Readonly Properties
class Point {
readonly x: number;
readonly y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
const p = new Point(5, 10);
p.x = 20; // Error: Cannot assign to 'x' because it is a read-only propertyInheritance
class Animal {
constructor(protected name: string) {}
eat(): void {
console.log(`${this.name} is eating.`);
}
}
class Dog extends Animal {
bark(): void {
console.log(`${this.name} says Woof!`);
}
}
const dog = new Dog("Rex");
dog.eat(); // Rex is eating.
dog.bark(); // Rex says Woof!Overriding Methods
class Animal {
makeSound(): void {
console.log("Some generic animal sound");
}
}
class Cat extends Animal {
override makeSound(): void {
console.log("Meow");
}
}
Note: Theoverridekeyword is optional but recommended — it makes your intent explicit and causes an error if the parent class doesn't actually have a matching method to override.
Abstract Classes
Like in many OOP languages, abstract classes cannot be instantiated directly and may define methods that subclasses are required to implement.
abstract class Shape {
abstract area(): number;
describe(): void {
console.log(`This shape has an area of ${this.area()}`);
}
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
area(): number {
return Math.PI * this.radius ** 2;
}
}
const circle = new Circle(5);
circle.describe(); // This shape has an area of 78.53981633974483Implementing Interfaces
A class can formally promise to match an interface's shape using implements.
interface Flyable {
fly(): void;
}
class Bird implements Flyable {
fly(): void {
console.log("The bird flies through the sky.");
}
}
Coming up next: Generics — writing flexible, reusable code that still stays fully type-safe.