On this page
Classes and Inheritance
TypeScript adds type safety to JavaScript classes. You get familiar OOP syntax with compile-time checks on properties, methods, and inheritance.
Basic Class
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak(): void {
console.log(`${this.name} makes a sound.`);
}
}
const dog = new Animal('Rex');
dog.speak(); // "Rex makes a sound."
Parameter Properties
TypeScript can declare and assign constructor parameters in one step:
class User {
constructor(
public id: number,
public name: string,
private password: string
) {}
greet(): string {
return `Hi, I'm ${this.name}`;
}
}
const u = new User(1, 'Alice', 'secret');
console.log(u.greet()); // "Hi, I'm Alice"
// console.log(u.password); // Error: private
Access Modifiers
| Modifier | Visibility |
|---|---|
public |
Default — accessible everywhere |
protected |
Class and subclasses only |
private |
Class only (enforced at compile time) |
readonly |
Set once, then immutable |
class BankAccount {
readonly accountNumber: string;
private balance: number;
constructor(accountNumber: string, initial: number) {
this.accountNumber = accountNumber;
this.balance = initial;
}
deposit(amount: number): void {
if (amount > 0) this.balance += amount;
}
getBalance(): number {
return this.balance;
}
}
Inheritance
class Vehicle {
constructor(protected brand: string) {}
describe(): string {
return `${this.brand} vehicle`;
}
}
class Car extends Vehicle {
constructor(brand: string, public doors: number) {
super(brand);
}
describe(): string {
return `${this.brand} car with ${this.doors} doors`;
}
}
const car = new Car('Toyota', 4);
console.log(car.describe()); // "Toyota car with 4 doors"
Use super() to call the parent constructor. Override methods with the same signature.
Abstract Classes
Abstract classes cannot be instantiated directly — subclasses must implement abstract members:
abstract class Shape {
abstract area(): number;
describe(): string {
return `Area: ${this.area().toFixed(2)}`;
}
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
area(): number {
return Math.PI * this.radius ** 2;
}
}
const circle = new Circle(5);
console.log(circle.describe()); // "Area: 78.54"
Implementing Interfaces
interface Printable {
print(): void;
}
class Report implements Printable {
constructor(public title: string, public body: string) {}
print(): void {
console.log(`=== ${this.title} ===\n${this.body}`);
}
}
Classes pair well with interfaces for defining contracts. In the next chapter, generics let you write reusable, type-safe functions and data structures.