Immutability¶
Rule¶
TypeScript's type system allows you to mark individual properties on an interface/class as readonly. This allows you to work in a functional way (an unexpected mutation is bad).
For more advanced scenarios there is a built-in type Readonly that takes a type
- Readability – readonly makes it clear which properties should never change.
- Safety – prevents accidental mutations that could introduce bugs.
- Compiler help – TypeScript enforces immutability at compile time.
- Functional style – supports immutability-first programming patterns.
- Reasoning – reduces side effects, making code easier to understand.
- Flexibility – Readonly
can lock down entire objects when needed.
Examples¶
🚨 DON’T¶
type User = {
id: string;
name: string;
};
const user: User = {id: "123", name: "Alice"};
user.id = "456"; // ❌ allowed, but unsafe
✅ DO¶
type User = {
readonly id: string;
name: string;
};
const user: User = {id: "123", name: "Alice"};
user.name = "Bob"; // ✅ allowed
user.id = "456"; // ❌ error: id is readonly
type Todo = {
title: string;
completed: boolean;
};
const todo: Readonly<Todo> = {title: "Learn TS", completed: false};
todo.completed = true; // ❌ error: all props are readonly