TypeScript Readonly Modifier

This chapter focuses on the readonly modifier in TypeScript, a feature that restricts properties from being reassigned after initialization. The readonly modifier ensures immutability for class properties and type declarations, enhancing type safety and reducing unintended changes.

Chapter Goal

  • To understand what the readonly modifier is and its purpose in TypeScript.
  • To learn how to use the readonly modifier for properties and types.
  • To explore practical applications of the readonly modifier for enforcing immutability.

Key Characteristics for TypeScript Readonly Modifier

  • Immutability: Ensures that a property cannot be reassigned after it is initialized.
  • Type Safety: Prevents accidental modification of constant values.
  • Declarative Syntax: Simple and clear syntax using the readonly keyword.
  • Class Properties: Often used for defining immutable class members.
  • Interfaces and Types: Applicable to object and array types for immutability.

Basic Rules for TypeScript Readonly Modifier

  1. Use readonly to prevent reassignment of properties after initialization.
  2. Apply readonly to class properties, interfaces, and type declarations.
  3. Initialize readonly properties either inline or in the constructor.
  4. Combine readonly with const for complete immutability.
  5. Avoid using readonly for properties that require updates.

Best Practices

  1. Use readonly for properties that represent constants or fixed values.
  2. Document the purpose of readonly properties to enhance code clarity.
  3. Combine readonly with TypeScript’s utility types like Readonly<T> for deep immutability.
  4. Avoid using readonly for mutable data or frequently updated values.
  5. Regularly review readonly declarations to ensure consistency with the code’s intent.

Syntax Table

Serial No Component Syntax Example Description
1 Basic Readonly Property readonly id: number; Declares a read-only property in a class.
2 Inline Initialization readonly name: string = ‘Alice’; Initializes a readonly property inline.
3 Constructor Assignment readonly balance: number; constructor(balance: number) { this.balance = balance; } Assigns a readonly property in the constructor.
4 Readonly Array readonly numbers: number[] = [1, 2, 3]; Declares a readonly array.
5 Readonly Utility Type Readonly<T> Makes all properties of T read-only.

Syntax Explanation

1. Basic Readonly Property

What is a Basic Readonly Property

A property that cannot be reassigned after it is initialized.

Syntax

class Product {

  readonly id: string;

 

  constructor(id: string) {

    this.id = id;

  }

}

Detailed Explanation

  • The id property is marked as readonly and can only be assigned in the constructor.
  • Attempts to reassign the id property will result in a compile-time error.

Example

const product = new Product(‘P123’);

console.log(product.id); // Output: P123

// product.id = ‘P124’; // Error: Cannot assign to ‘id’ because it is a read-only property.

Output

P123

Notes

  • Use readonly for properties that represent fixed identifiers or constants.

Warnings

  • Ensure that readonly properties are initialized either inline or in the constructor.

2. Inline Initialization

What is Inline Initialization

Assigning a value to a readonly property directly during its declaration.

Syntax

class User {

  readonly name: string = ‘Default User’;

}

Detailed Explanation

  • Inline initialization sets the readonly property at the time of declaration.
  • This approach is useful for properties with default values that rarely change.

Example

const user = new User();

console.log(user.name); // Output: Default User

// user.name = ‘Admin’; // Error: Cannot assign to ‘name’ because it is a read-only property.

Output

Default User

Notes

  • Inline initialization simplifies the class constructor for fixed properties.

Warnings

  • Avoid inline initialization for properties that require dynamic assignment.

3. Constructor Assignment

What is Constructor Assignment

Initializing a readonly property within the class constructor.

Syntax

class Account {

  readonly balance: number;

 

  constructor(balance: number) {

    this.balance = balance;

  }

}

Detailed Explanation

  • Constructor assignment provides flexibility to initialize readonly properties with dynamic values.
  • This approach is commonly used for properties dependent on constructor arguments.

Example

const account = new Account(1000);

console.log(account.balance); // Output: 1000

// account.balance = 2000; // Error: Cannot assign to ‘balance’ because it is a read-only property.

Output

1000

Notes

  • Constructor assignment is ideal for properties initialized with runtime values.

Warnings

  • Ensure that all readonly properties are assigned within the constructor.

4. Readonly Array

What is a Readonly Array

An array declared with the readonly modifier, preventing reassignment of the array reference.

Syntax

class Data {

  readonly values: number[] = [1, 2, 3];

}

Detailed Explanation

  • The array reference is immutable, but the array contents can still be modified.
  • Use TypeScript’s ReadonlyArray<T> for true immutability of array contents.

Example

const data = new Data();

console.log(data.values); // Output: [1, 2, 3]

// data.values = [4, 5, 6]; // Error: Cannot assign to ‘values’ because it is a read-only property.

data.values.push(4); // This is allowed.

console.log(data.values); // Output: [1, 2, 3, 4]

Output

[1, 2, 3]

[1, 2, 3, 4]

Notes

  • Use ReadonlyArray<T> for strict immutability if modifying contents should be restricted.

Warnings

  • Remember that the readonly modifier applies only to the reference, not the array elements.

5. Readonly Utility Type

What is the Readonly Utility Type

A TypeScript utility type that makes all properties of a type read-only.

Syntax

type ReadonlyObject = Readonly<{ name: string; age: number }>;

 

const obj: ReadonlyObject = { name: ‘Alice’, age: 25 };

Detailed Explanation

  • The Readonly utility type applies the readonly modifier to every property of a type.
  • This ensures deep immutability for object structures.

Example

console.log(obj.name); // Output: Alice

// obj.name = ‘Bob’; // Error: Cannot assign to ‘name’ because it is a read-only property.

Output

Alice

Notes

  • Combine Readonly<T> with nested types for comprehensive immutability.

Warnings

  • Avoid overusing Readonly for types that require frequent updates.

Real-Life Project

Project Name

Immutable Configuration Settings

Project Goal

Demonstrates how to use the readonly modifier to define immutable configuration settings for an application.

Code for This Project

class Config {

  readonly appName: string;

  readonly version: string;

  readonly features: ReadonlyArray<string>;




  constructor(appName: string, version: string, features: string[]) {

    this.appName = appName;

    this.version = version;

    this.features = features;

  }

}




const config = new Config('MyApp', '1.0.0', ['login', 'dashboard']);

console.log(config.appName); // Output: MyApp

console.log(config.features); // Output: ['login', 'dashboard']

// config.appName = 'NewApp'; // Error: Cannot assign to 'appName' because it is a read-only property.

// config.features.push('analytics'); // Error if using `ReadonlyArray`.

Save and Run

  1. Save the code in your development environment, such as Visual Studio Code, ensuring the file is named config.ts.
  2. Compile the TypeScript code into JavaScript using the command tsc config.ts in your terminal.
  3. Execute the resulting JavaScript file using the command node config.js.

Expected Output

MyApp

[‘login’, ‘dashboard’]