Typescript Readonly and Constant Types: Ensure immutability for certain types
In TypeScript, immutability can be enforced for certain types by using readonly properties and const declarations.
1. const for Variables
When you declare a variable with const
, it cannot be reassigned. However, for objects and arrays, const
only prevents reassignment of the variable itself—not its contents.
const name = "Amir"; // Primitive type, fully immutableconst person = { name: "Amir", age: 25 };person.age = 26; // This is allowed since `const` does not freeze object properties.
2. readonly for Object Properties
To make object properties immutable, use the readonly
modifier on properties within interfaces or type aliases. This prevents these properties from being modified once they are set.
interface Person {readonly name: string;readonly age: number;}const person: Person = { name: "Amir", age: 25 };// person.age = 26; // Error: Cannot assign to 'age' because it is a read-only property.
In this case, name
and age
are immutable because of the readonly
modifier.
3. Readonly Utility Type for Full Object Immutability
TypeScript provides a built-in utility type, Readonly<T>
, that converts all properties of a type T
to readonly
. This is useful for creating deeply immutable objects without manually marking each property as readonly
.
type Person = {name: string;age: number;};const person: Readonly<Person> = { name: "Amir", age: 25 };// person.age = 26; // Error: Cannot assign to 'age' because it is a read-only property.
4. readonly for Arrays
For arrays, readonly
can be used to prevent modification of the array structure (like adding or removing elements). This ensures the array itself remains immutable.
const numbers: readonly number[] = [1, 2, 3];// numbers.push(4); // Error: Property 'push' does not exist on type 'readonly number[]'.
Combining const and readonly
For maximum immutability:
Use
const
for the variables that don’t change.Use
readonly
for object properties.Use
Readonly<T>
for complete immutability at the type level.
By using these TypeScript features, you can ensure that values remain unchanged after their initial assignment, enhancing the robustness of your code through immutability.