Classes
TypeScript classes look almost identical to JavaScript classes, with one major addition: access modifiers that control which properties and methods can be reached from outside the class, enforced by the compiler.
A typed class
class BankAccount {
private balance: number;
public readonly owner: string;
constructor(owner: string, startingBalance: number) {
this.owner = owner;
this.balance = startingBalance;
}
deposit(amount: number): void {
this.balance += amount;
console.log(`Deposited ${amount}. New balance: ${this.balance}`);
}
}
const acc = new BankAccount("Priya", 100);
acc.deposit(50);
console.log(acc.balance);
account.ts:19:14 - error TS2341: Property 'balance' is private and only accessible within class 'BankAccount'.
private balance means only code inside BankAccount itself can read or write balance — the last line fails to compile precisely because it tries to reach in from outside. Remove that line and the deposit example runs and prints normally.
Implementing an interface
interface Shape {
area(): number;
}
class Rectangle implements Shape {
constructor(private width: number, private height: number) {}
area(): number {
return this.width * this.height;
}
}
const rect = new Rectangle(4, 5);
console.log(rect.area());
20
implements Shape makes the compiler check that Rectangle actually provides everything Shape requires — if area() were missing or returned the wrong type, this wouldn't compile. Marking constructor parameters private directly (private width: number) is a shortcut that both declares the property and assigns it in one step.
private and protected are compile-time-only concepts, just like every other TypeScript type annotation — once compiled to JavaScript, balance is an ordinary property that outside code can absolutely read and write, TypeScript just won't let your own typed code do it without an error. If you need privacy that's actually enforced at runtime, use a real private field with a # prefix (#balance), which JavaScript itself hides.