Typescript Readonly And Static Properties Complete Guide

 Last Update:2025-06-22T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    6 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of TypeScript Readonly and Static Properties

Readonly Properties

Readonly properties provide a way to lock the value of a property after it has been initialized in a class constructor or as a class property. It is a powerful feature for ensuring that certain properties are not modified after their initial assignment, which aligns with immutability principles often seen in functional programming.

Explanation:

  • Usage: The readonly modifier is added to any property within a class definition to indicate its value should not change once set.
  • Initialization: A readonly property must be initialized either at the time of declaration or in the class constructor.

Syntax:

class Employee {
    readonly empNo: number;
    readonly empName: string;

    constructor(employeeNumber: number, employeeName: string) {
        this.empNo = employeeNumber;
        this.empName = employeeName;
    }
}

In the above code:

  • empNo and empName are marked as readonly, meaning they cannot be altered after the instance is created.
  • If you attempt to reassign the value of empNo or empName on an instance of Employee, TypeScript will throw a compile-time error.

Benefits:

  • Enforce Immutable Data: Ensures that the data integrity is maintained and prevents accidental modifications.
  • Improved Predictability: Increases predictability by guaranteeing that certain values will remain constant throughout the lifecycle of an object, reducing potential bugs.

Static Properties

Static properties, on the other hand, belong to the class itself rather than to any specific instance of the class. This means they are shared across all instances of the class and can also be accessed directly from the class without needing to instantiate it.

Explanation:

  • Usage: The static keyword is used to define a static property within a class.
  • Access: Static properties can be accessed using the class name followed by a dot syntax.

Syntax:

class MathUtility {
    static PI: number = 3.14159;
    
    static areaOfCircle(radius: number): number {
        return radius * radius * MathUtility.PI;
    }
}

console.log(MathUtility.PI); // Accessing static property directly via class name
console.log(MathUtility.areaOfCircle(5)); // Calling static method directly via class name

In the example provided:

  • PI is a static property shared among all instances of MathUtility.
  • The areaOfCircle method is also static and utilizes the PI constant directly without requiring an instance of MathUtility.

Benefits:

  • Shared Across Instances: Useful for utility functions or properties that are common to all instances of a class, promoting memory efficiency.
  • Direct Accessibility: Allows direct access to the class's functionality without needing to create an instance first.

Combination of Readonly and Static Properties

You can also combine readonly with static to create a static property that is both immutable and shared among class instances.

Syntax:

class AppConfig {
    static readonly BASE_API_URL: string = 'https://api.example.com/';
}

console.log(AppConfig.BASE_API_URL); // Outputs: https://api.example.com/
// AppConfig.BASE_API_URL = 'https://new.example.com/'; // This will cause a compile-time error as BASE_API_URL is readonly

In the AppConfig class:

  • BASE_API_URL is a static readonly property, meaning its value cannot be changed after it is initialized.

Use Case: This approach is ideal for configuration values such as API endpoints, default settings, etc., where you want these values to be consistent and immutable throughout the application life cycle.

Summary of Key Points

  • Readonly: Locks the value of a property, providing immutability and helping prevent accidental changes.
  • Static: Belongs to the class itself rather than individual instances, allowing shared state and methods.
  • Readonly-Static: Combines both features for properties shared and immutable at the class level.

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement TypeScript Readonly and Static Properties

TypeScript Readonly Properties

readonly properties allow you to define a class member that cannot be changed once it is set during the initialization of the object.

Step-by-Step Example:

  1. Define the Class: Start by creating a simple class called Product.

  2. Add a readonly Property: Add a readonly property to the class named productID.

  3. Initialize the readonly Property: Initialize the readonly property through the constructor.

Code:

// Step 1: Define the class Product
class Product {
    // Step 2: Add readonly property productID
    readonly productID: number;

    // Other non-readonly properties
    name: string;
    price: number;

    // Step 3: Initialize the readonly property
    constructor(id: number, name: string, price: number) {
        this.productID = id; 
        this.name = name;
        this.price = price;
    }

    // Method to print product information
    getProductInfo() {
        console.log(`Product ID: ${this.productID}, Name: ${this.name}, Price: $${this.price}`);
    }
}

// Create an instance of Product
const product = new Product(101, 'Laptop', 999);

// Try to change productID (will cause a compilation error)
// product.productID = 102; // Uncommenting this line will result in an error

// You can still access and use productID, but not change it
product.getProductInfo(); // Output: Product ID: 101, Name: Laptop, Price: $999

Explanation:

  • Step 1: We create a class named Product. Classes are blueprints for objects in TypeScript.
  • Step 2: We declare a property named productID with the readonly keyword. This property cannot be modified after it is set.
  • Step 3: In the constructor, we initialize the productID. Note that you can only assign a value to a readonly property within the constructor or directly at its declaration.
  • When you try to modify productID outside the constructor (as shown in the commented line), TypeScript will throw a compilation error indicating that assignment is not allowed to a readonly property.

TypeScript Static Properties

static properties belong to the class itself rather than the instances of the class. They are shared among all instances of the class.

Step-by-Step Example:

  1. Create the Class: Define a class named Employee.

  2. Add a static Property: Add a static property named companyName.

  3. Access the static Property: Access the static property both inside the class and outside the class using the class name.

Code:

Top 10 Interview Questions & Answers on TypeScript Readonly and Static Properties

1. What are readonly properties in TypeScript, and how do they differ from regular properties?

Answer: In TypeScript, readonly properties are used to indicate that a member of the class (typically a property) should not be modified after its initial assignment, either within the constructor or directly on the instance. Unlike regular properties which can be changed at any point after their initialization, readonly properties provide an immutability layer ensuring that the original value remains unchanged through the lifecycle of the object.

class Config {
    readonly apiEndpoint: string; // This cannot be reassigned outside the constructor
    
    constructor(apiEndpoint: string) {
        this.apiEndpoint = apiEndpoint; 
    }
}

const settings = new Config("https://example.com/api");
settings.apiEndpoint = "https://example.org/api"; // Error: Cannot assign to 'apiEndpoint' because it is a read-only property.

2. Can you use readonly with both fields and parameters in TypeScript constructors?

Answer: Yes, TypeScript allows you to use readonly with both class fields and constructor parameters. Using readonly directly in the constructor parameter list automatically creates a readonly field with the same name and assigns it the value of that parameter. This shorthand simplifies the code.

class User {
    readonly username: string;
    readonly email: string;

    constructor(username: string, email: string) {
        this.username = username;
        this.email = email;
    }
}

// Simplified constructor using readonly parameters
class UserSimplified {
    constructor(readonly username: string, readonly email: string) {}
}

const bob = new UserSimplified("bob", "bob@example.com");
bob.username = "bobby"; // Error: 'username' is a read-only property.

3. How can static properties be accessed in TypeScript, and what is their purpose?

Answer: Static properties are shared across all instances of a class rather than being unique to an individual instance. They are commonly used for constants or utility functions related to the class but not specific to the instantiated objects. Static properties can be accessed without creating an instance of the class and are typically useful for defining class-related constants.

To access static properties, you use the class name followed by the dot operator and the property name.

class Circle {
    static pi = 3.142;
    
    constructor(public radius: number) {}
    
    area(): number {
        return this.radius * this.radius * Circle.pi; // Use Circle.pi instead of this.pi
    }
}

console.log(Circle.pi); // Output: 3.142

const myCircle = new Circle(5);
console.log(myCircle.area()); // Output: 78.55

The pi property here is accessible globally via Circle.pi, not requiring any instance creation.

4. Is it possible to modify static properties after they are defined in TypeScript?

Answer: Yes, static properties can be modified just like regular properties but these modifications affect all instances that share the static property.

class Vehicle {
    static numOfVehicles = 0;
    
    constructor() {
        Vehicle.numOfVehicles++;
    }
}

console.log(Vehicle.numOfVehicles); // Output: 0

const car1 = new Vehicle();
console.log(Vehicle.numOfVehicles); // Output: 1

Vehicle.numOfVehicles = 5; // Manual modification
const car2 = new Vehicle();
console.log(Vehicle.numOfVehicles); // Output: 6 (not 2)

Here, numOfVehicles is a static property that counts the number of vehicle instances created. It can be changed manually, affecting future vehicle count calculations.

5. What happens if you combine readonly with static in a TypeScript class?

Answer: When readonly is combined with static, it creates a static property whose value cannot be changed after its initial assignment. Just like non-static readonly properties, static readonly properties must be initialized at the time of declaration or within the constructor itself.

class MathConstants {
    static readonly e = Math.E;     // Euler's number e
    static readonly pi = Math.PI;   // PI

    constructor() {} // No need to reinitialize static readonly properties
}

console.log(MathConstants.e);  // Output: 2.718281828459045
console.log(MathConstants.pi); // Output: 3.141592653589793

MathConstants.pi = 3.14; // Error: Cannot assign to 'pi' because it is a read-only property.

6. Are readonly and static modifiers exclusive or can they be used together?

Answer: No, readonly and static are not mutually exclusive; they can be used together in TypeScript to define a constant that is shared among all instances of the class.

Example provided in Q5 illustrates this well.

7. Can private class members be both readonly and static in TypeScript?

Answer: Yes, private members can also be both static and readonly. This encapsulates the private static read-only property within the class definition making it only accessible from methods and other static members inside the class.

class Logger {
    private static readonly timestampFormat = "HH:mm:ss";

    log(message: string) {
        const timestamp = new Date().toISOString().slice(-13, -1); // Assuming this returns the format
        console.log(`[${timestamp}] ${message}`);
    }
}

// Logger.timestampFormat = "HH:mm"; // Error: because it is private

8. How do abstract classes utilize readonly and static properties in TypeScript?

Answer: Abstract classes can also define readonly and static properties. These properties can be inherited by child classes but, following the rules of readonly and static, cannot be reassigned unless they are overridden and declared again in the derived class.

abstract class BaseConfig {
    static readonly defaultTimeout = 2000;

    protected readonly serviceUrl: string;
    
    constructor(serviceUrl: string) {
        this.serviceUrl = serviceUrl;
    }
}

class ProdConfig extends BaseConfig {
    static readonly defaultTimeout = 5000;

    override readonly serviceUrl = "https://prod.example.com";

    constructor() {
        super(ProdConfig.defaultTimeout.toString());
    }
}

console.log(BaseConfig.defaultTimeout); // Output: 2000
console.log(ProdConfig.defaultTimeout); // Output: 5000

const prodConf = new ProdConfig();
console.log(prodConf.serviceUrl); // Output: "https://prod.example.com"
prodConf.serviceUrl = "new-url";  // Error: 'serviceUrl' is a read-only property.

In the example above, defaultTimeout is a static, readonly property shared among various configurations. Each configuration class can modify its value as needed.

9. Are readonly or static modifiers available for method parameters in TypeScript?

Answer: Neither readonly nor static are applicable to method parameters in TypeScript. Method parameters represent local variables within the scope of the method and thus should not be labeled as readonly or static.

class Greet {
    greet(readonly name: string) { // Error: A parameter property may not be declared using 'readonly'.
        console.log(name);
    }

    static announce(static message: string) { // Error: 'static' modifier cannot appear on a parameter.
        console.log(message);
    }
}

10. When should you prefer using readonly over const in TypeScript?

Answer: While both readonly and const enforce immutability, their usage differs based on scope:

  • const: Use in variable declarations when the variable does not change after its initial assignment within the file. It applies to primitive types as well as object reference.

  • readonly: Use on class properties when ensuring that a given property value remains constant throughout an object’s lifespan.

You May Like This Related .NET Topic

Login to post a comment.