TypeScript - Readonly Properties



TypeScript provides us with readonly keyword to make a property in class, type or interface as read-only. The readonly properties can be accessed outside the class but their values can't be modified.

By using the readonly properties, you can ensure that no one can modify the property outside the object, but they can read the value of the property.

Syntax

To define readonly properties in TypeScript, we prefix the property name with the readonly keyword.

readonly propName: type;

Where,

  • In the above syntax, 'readonly' is a keyword.

  • The 'propName' is a property name of the readonly property.

  • The 'type' is a property type of the readonly property.

The encapsulating entity may be a class or an interface in TypeScript.

You can replace propertyName with the desired name for the readonly property, and type with the appropriate data type.

The readonly Properties with Interface

Interface is used to define the prototype of the object. We can define the readonly properties in the interface. Let's understand it via the example below.

Example

In the code below, we have defined the Car interface containing the model, year, and fuel properties. Here, the fuel property is readonly, which can be initialized only while creating the object but can't be changed after creating the object.

After that, we have created the object of the Car type and initialized all properties.

You can try to change the value of the fuel property of the car object, and observe the error.

//  Defining the interface for the car
interface Car {
    model: string;
    year: number;
    readonly fuel: string;
}

// Defining the car object
let car: Car = {
    model: 'BMW',
    year: 2019,
    fuel: 'petrol'
}

console.log(car.model);
console.log(car.year);
console.log(car.fuel);

// Error: Cannot assign to 'fuel' because it is a read-only property.
// car.fuel = 'diesel';

On compiling, it will generate the following JavaScript code.

// Defining the car object
let car = {
    model: 'BMW',
    year: 2019,
    fuel: 'petrol'
};
console.log(car.model);
console.log(car.year);
console.log(car.fuel);
// Error: Cannot assign to 'fuel' because it is a read-only property.
// car.fuel = 'diesel';

Output

The output of the above example code is as follows −

BMW
2019
petrol

The readonly Properties with Classes

The class can also contain readonly properties similar to the interfaces. The value of the readonly properties can be initialized in the constructor() method while creating the object. You can't change the value of the readonly properties of the class using the class instance.

Example

In the code below, we have defined the car class which contains the model and price properties. It also contains the 'type' readonly property.

In the constructor() method, we initialize the values of all properties including the 'type' readonly property.

The display() method prints the values of all properties.

After that, we have created the object of the car class. Now, you can try to change the value of the 'type' property of the car object, it will throw an error as it is readonly.

// Defining the class for car
class Car {
    // Properties
    model: string;
    price: number;
    readonly type: string = 'Car';
    // Constructor
    constructor(model: string, price: number, type: string) {
        this.model = model;
        this.price = price;
        this.type = type;
    }
    // Method
    display(): void {
        console.log(`Model: ${this.model}, Price: ${this.price}, Type: ${this.type}`);
    }
}

// Creating object of Car class
let car = new Car('BMW', 1000000, 'Sedan');
car.display();

// Try to change the value of readonly property
// car.type = 'SUV'; // Error: Cannot assign to 'type' because it is a read-only property.

On compiling, it will generate the following JavaScript code.

// Defining the class for car
class Car {
    // Constructor
    constructor(model, price, type) {
        this.type = 'Car';
        this.model = model;
        this.price = price;
        this.type = type;
    }
    // Method
    display() {
        console.log(`Model: ${this.model}, Price: ${this.price}, Type: ${this.type}`);
    }
}
// Creating object of Car class
let car = new Car('BMW', 1000000, 'Sedan');
car.display();
// Try to change the value of readonly property
// car.type = 'SUV'; // Error: Cannot assign to 'type' because it is a read-only property.

Output

The output of the above code example is as follows −

Model: BMW, Price: 1000000, Type: Sedan

The readonly Properties with Type Aliases

Type aliases are used to define a type for the object. It can also contain readonly properties similar to the interface.

Example

In the code below, 'Point' is a type alias that contains 'x' and 'y' properties and both are readonly.

After that, we defined the P1 point of type 'Point' and initialized the values of 'X' and 'Y' properties while defining it.

Next, try to change the value of any property of the 'P1' point. It will throw an error as both properties of P1 are readonly.

//  Readonly Properties with type alias
type Point = {
    readonly x: number;
    readonly y: number;
}

let p1: Point = { x: 10, y: 20 };
// p1.x = 5; // Error

console.log(p1.x, p1.y);

On compiling, it will generate the following JavaScript code.

let p1 = { x: 10, y: 20 };
// p1.x = 5; // Error
console.log(p1.x, p1.y);

Output

The output is as follows −

10 20

Const vs. readonly Properties

The 'const' keyword is similar to the 'readonly' keyword but there are some minor differences.

  • The 'const' keyword is used to declare the constant variables, whereas the 'readonly' keyword is used to declare the readonly properties of objects.
  • You need to assign value to the variable declared using the 'const' keyword while declaring it, but for 'readonly' properties, you can assign values while creating the object.
  • The value of 'const' variables can't be changed after declaring it, and the value of 'readonly' properties can't be changed outside the object or class.

When to Use Readonly

  • Data Integrity: When you want to ensure that certain properties of an object don't change after their initial assignment.
  • Functional Programming: It helps in programming paradigms where immutability is a cornerstone.
  • API Contracts: When creating objects that are exposed to external users and you need to guarantee that the internal state won't be altered unexpectedly.
Advertisements