When working with objects, you sometimes want to prevent accidental changes to certain properties. TypeScript’s readonly modifier helps you lock properties so they can’t be reassigned after creation.
1. The readonly Modifier in Interfaces or Type Aliases
You can add readonly directly to each property:
type User = {
readonly name: string;
readonly age: number;
};
-
nameandageare both read-only. - Once a
Userobject is created, these properties cannot be reassigned.
Example:
const user: User = {
name: "Safal",
age: 10,
};
user.age = 12; // ❌ Error: Cannot assign to 'age' because it is a read-only property
TypeScript’s compiler enforces immutability at compile time.
(At runtime, it’s still a normal JavaScript object, but TypeScript stops you from writing code that would mutate it.)
2. Readonly<T> Utility Type
Instead of writing readonly on every property, TypeScript provides a built-in utility type:
type User1 = {
name: string;
age: number;
};
const user1: Readonly<User1> = {
name: "Safal",
age: 10,
};
Here, Readonly<User1> creates a new type identical to User1, but with all properties marked as readonly.
It’s equivalent to:
type ReadonlyUser1 = {
readonly name: string;
readonly age: number;
};
Any attempt to reassign:
user1.name = "New Name"; // ❌ Error: Cannot assign to 'name' because it is a read-only property
3. When to Use readonly
- Immutable data models: Prevent unintended mutations in configuration objects or Redux state.
- API boundaries: When exposing data to other parts of the app that should not be modified.
- Functional programming patterns: Enforce immutability by design.
4. Key Points to Remember
-
Compile-time only:
readonlyis enforced by TypeScript’s type checker. JavaScript doesn’t freeze the object automatically.
- If you need runtime immutability, you can also use
Object.freeze().-
Shallow:
readonlyonly applies to the top-level properties, not nested objects.
-
Shallow:
Example:
type Nested = {
readonly info: { value: number };
};
const x: Nested = { info: { value: 1 } };
x.info.value = 2; // ✅ Allowed, because `value` is not marked readonly
Quick Comparison
| Feature | Example | Effect |
|---|---|---|
| Property modifier | readonly name: string; |
Mark individual properties as immutable |
| Utility type | Readonly<User> |
Make all properties of a type read-only |
Summary
Use readonly when you want TypeScript to guarantee immutability of object properties.
- Add
readonlydirectly to specific properties for fine-grained control. - Use the
Readonly<T>utility to lock down an entire type at once.
This helps keep your data structures predictable and protects against accidental mutation in large codebases.
Top comments (0)