Back to all snippets
Library/TypeScript/Deep Readonly Type
typescriptadvancedtypesimmutabilityutilities

How to implement Deep Readonly Type in Typescript

Make all nested properties readonly

Quick Answer

`DeepReadonly<T>` recursively applies the `readonly` modifier to every property at every nesting level, making entire object trees immutable.

Code Snippet

1type DeepReadonly<T> = {
2  readonly [P in keyof T]: T[P] extends object
3    ? DeepReadonly<T[P]>
4    : T[P];
5};
6
7// Usage
8interface Config {
9  api: { url: string; timeout: number };
10  features: { darkMode: boolean };
11}
12
13type ReadonlyConfig = DeepReadonly<Config>;

What is Deep Readonly Type?

TypeScript's built-in Readonly only makes the top-level properties read-only; nested objects remain mutable. DeepReadonly applies the readonly modifier recursively to every level, making entire object trees immutable at the type level — ideal for Redux state, configuration objects, and domain models.

How It Works

  1. 1Use a mapped type with `readonly [P in keyof T]` for every property.
  2. 2For each property value, check if it extends `object` — if yes, recurse with `DeepReadonly<T[P]>`; otherwise keep the type as-is.
  3. 3Arrays and tuples are also covered because they extend `object`.

Common Use Cases

  • Redux state - Prevent accidental mutations of deeply nested state
  • Configuration - Enforce that config objects are never modified after init
  • Domain models - Make value objects fully immutable by convention
  • Shared constants - Export deeply immutable constants safely

Key Benefits

  • Enforces immutability at every nesting level
  • Catches accidental mutations at compile time
  • Works with arrays, tuples, and nested objects
  • Zero runtime overhead — purely a type-level constraint

Common Mistakes to Avoid

  • Applying DeepReadonly to types with circular references can cause infinite type instantiation in older TypeScript versions.
  • Expecting it to prevent mutations at runtime — readonly is a compile-time check only.
  • Forgetting that readonly arrays disallow push/pop — you may need a separate mutable copy for transformations.

Quick Tips

  • Click the "Copy" button above to copy the code to your clipboard
  • This code is production-ready and can be used in your projects immediately
  • Check out related snippets below for more typescript examples

Frequently Asked Questions

Does DeepReadonly work on arrays?

Yes. Arrays extend `object`, so the recursive branch applies `DeepReadonly` to the element type as well. The resulting type will be `ReadonlyArray<DeepReadonly<Element>>`.

About This Typescript Code Snippet

This free typescript code snippet for deep readonly type is production-ready and copy-paste friendly. Whether you are building a web app, API, or frontend interface, this advanced-level example will help you implement deep readonly type quickly and correctly.

All snippets in the Snippetly library follow typescript best practices and are tested for real-world use. You can adapt this code to work with React, Vue, Node.js, or any project that uses typescript.

Tags: types, immutability, utilities  | Language: typescript  | Difficulty: advanced  | Category: TypeScript

Build Your Own Snippet Library

Organise your team's code snippets with Snippetly. Share knowledge and boost productivity across your organisation.