2 min read

TypeScript: readonly vs const

In TypeScript, both readonly and const are used to prevent mutation, but they apply to different scopes.

1. The Rule of Thumb

  • Use const for variables.
  • Use readonly for properties (of interfaces, classes, or type literals).

2. const (Variables)

const is a JavaScript (ES6) feature. It defines a block-scoped variable that cannot be reassigned.

const x = 10;
// x = 20; // Error: Assignment to constant variable.

Important: const only prevents reassignment of the variable reference. It does not make the object immutable.

const user = { name: "Alice", age: 30 };

// You CANNOT change the reference
// user = { name: "Bob", age: 40 }; // Error

// You CAN change the properties
user.age = 31; // OK

3. readonly (Properties)

readonly is a TypeScript feature. It marks specific properties of an object as immutable.

In Interfaces and Types

interface Point {
    readonly x: number;
    readonly y: number;
}

let p: Point = { x: 10, y: 20 };
// p.x = 5; // Error: Cannot assign to 'x' because it is a read-only property.

In Classes

Readonly properties in classes can only be initialized at their declaration or inside the constructor.

class Greeter {
    readonly greeting: string;

    constructor(message: string) {
        this.greeting = message;
    }

    changeGreeting() {
        // this.greeting = "Hello"; // Error
    }
}

4. Readonly<Type> Utility

If you want to make all properties of an object readonly, you don't need to mark them one by one. You can use the Readonly<T> utility type.

interface User {
    name: string;
    age: number;
}

const user: Readonly<User> = { name: "Alice", age: 30 };

// user.age = 31; // Error

5. ReadonlyArray<Type>

Standard arrays are mutable. ReadonlyArray<T> (or readonly T[]) removes methods that mutate the array (like push, pop, splice).

const a: number[] = [1, 2, 3];
const ro: ReadonlyArray<number> = a;

// ro[0] = 12; // Error
// ro.push(5); // Error

// Non-mutating methods are fine
console.log(ro.length);
console.log(ro.slice(1));

6. Summary

Feature const readonly
Target Variables Object Properties
Origin JavaScript (Runtime) TypeScript (Compile-time)
Behavior Prevents reassignment Prevents property mutation
Deep Immutability? No No (unless recursive)

programming/javascript/typescript/typescript