New: We've launched a brand new Coding Challenges section! Check out these interactive, real-world exercises to level up your skills.Explore Challenges
FrontendPrep
typescriptEasy

TypeScript: Readonly and Utility Modifiers

Loading...

Understand how to enforce immutability in TypeScript. Learn about the readonly modifier, Readonly<T> utility type, const assertions, and readonly arrays.

Arvind M
Arvind MLinkedIn

TypeScript: Readonly and Utility Modifiers

One of the common frontend interview questions that focuses on code styling and clean architecture is:

How do you declare immutable properties in TypeScript? What is the difference between readonly, the Readonly<T> utility type, and as const assertions?

TypeScript provides multiple mechanisms to enforce compile-time immutability, allowing you to catch unintended side effects (like mutating state objects directly instead of using setState/reducers).


1. The readonly Property Modifier

The readonly keyword is applied to individual properties in interfaces, type aliases, or classes:

interface User {
  readonly id: string;
  name: string;
}
 
const user: User = { id: "123", name: "Alice" };
user.name = "Bob"; // ✅ Allowed
user.id = "456";   // ❌ Compile Error: Cannot assign to 'id' because it is a read-only property.

Class usage:

class Config {
  readonly apiUrl: string;
  constructor(url: string) {
    this.apiUrl = url; // ✅ Allowed only in constructors
  }
}

2. The Readonly<T> Utility Type

Instead of manually adding readonly to every key in a large object shape, you can wrap the entire type in the Readonly<T> utility type, which maps all properties to read-only recursively.

interface State {
  theme: string;
  isLoading: boolean;
}
 
const state: Readonly<State> = {
  theme: "dark",
  isLoading: false
};
 
state.theme = "light"; // ❌ Compile Error: Cannot assign to 'theme' because it is a read-only property.

3. Readonly Arrays (ReadonlyArray<T> / readonly Type[])

Standard arrays in JavaScript are mutable (methods like push(), splice(), and sort() modify the original array in place). TypeScript provides a specific immutable array type:

const numbers: readonly number[] = [1, 2, 3];
// Alternative: const numbers: ReadonlyArray<number> = [1, 2, 3];
 
numbers.push(4);  // ❌ Compile Error: Property 'push' does not exist on type 'readonly number[]'.
numbers[0] = 10;  // ❌ Compile Error: Index signature in type 'readonly number[]' only permits reading.

4. readonly vs. const vs. as const

It is common to confuse these constructs. Here is how they stack up:

  • const: A standard JavaScript runtime variable declaration. It prevents variable re-assignment, but does not prevent mutating the object's properties.
  • readonly: A TypeScript compiler flag. It prevents property reassignment on an object at compile-time.
  • as const: A const assertion. It locks down both the array/object references, keeps literal types from widening, and recursively sets all nested properties to readonly.
const config = {
  port: 8080
} as const;
 
config.port = 9000; // ❌ Compile Error: Cannot assign because it is read-only

Key Contrast Summary

Featureconst variablereadonly propertyas const assertion
System LevelJavaScript RuntimeTypeScript CompilerTypeScript Compiler
ScopeVariable ReferenceObject PropertyEntire Literal Expression
Deep Immutability❌ No❌ No (requires nesting)✅ Yes (recursively sets all to read-only)
Type Widening✅ Widen strings to string✅ Widened❌ Kept as strict literal types

Key Takeaways

  • readonly Modifier: Prevents properties on an interface or class from being reassigned after initialization.
  • Readonly Utility: Wraps an entire object type to make all its properties read-only without manual keys.
  • as const Assertions: Locks down literal values recursively to read-only, preventing type widening to primitive types.
  • ReadonlyArray: Prevents mutating array methods like push and pop from running on an array at compile-time.

Finished practicing this challenge?

Mark it as completed to track your progress, or bookmark it to review later.

Loading...

Share this Resource

Help other developers level up by sharing this study guide.

⚡ Weekly newsletter

Crack Your Next Frontend Interview.

Join senior engineers who receive practical, deep-dive frontend challenges, detailed concepts, and blueprints directly in their inbox.

  • Senior level React, JS, and CSS interview blueprints
  • System Design & performance optimization deep-dives
  • 100% free, zero spam, unsubscribe with one click

Join the Study Track

We value your privacy. Unsubscribe at any time.

More Technical Questions

Expand your mastery. Deep dive into other frontend interview challenges in this category.