CodeWithMihir

TypeScript Tutorial

TypeScript Readonly Utility Type Explained

Learn how the Readonly utility type works in TypeScript, including immutable object properties, configuration objects, and limitations.

Welcome back! I am Mihir, and in this lesson we will learn the Readonly utility type in TypeScript.

Readonly<T> makes every property in T readonly.


Basic Readonly Example

type User = {
  id: number;
  name: string;
};

type ReadonlyUser = Readonly<User>;

ReadonlyUser behaves like:

type ReadonlyUser = {
  readonly id: number;
  readonly name: string;
};

Using Readonly

const user: Readonly<User> = {
  id: 1,
  name: "Mihir",
};

Invalid:

user.name = "Mihir Soni";

Readonly properties cannot be reassigned.


Useful for Config Objects

type AppConfig = {
  appName: string;
  apiUrl: string;
};

const config: Readonly<AppConfig> = {
  appName: "CodeWithMihir",
  apiUrl: "/api",
};

This communicates that config values should stay stable.


Readonly Is Not Deep

type Cart = {
  items: string[];
};

const cart: Readonly<Cart> = {
  items: [],
};

cart.items.push("Keyboard");

This is allowed because Readonly only protects the top-level property.

Invalid:

cart.items = [];

Readonly with Arrays

For arrays, use ReadonlyArray<T>.

const names: ReadonlyArray<string> = ["Mihir", "Alex"];

Invalid:

names.push("Sara");

Readonly arrays do not allow mutation methods like push.


Quick Recap

  • Readonly<T> makes object properties readonly.
  • It prevents reassignment of top-level properties.
  • It is useful for config and stable data.
  • It is not deep immutability.
  • Use ReadonlyArray<T> for arrays.

Next up, we will learn Pick →.