To make an object property read-only or immutable, you can use the readonly
keyword before the property name in the type declaration for the object in TypeScript.
TL;DR
// Object type declaration
// where the name property is read-only
interface PersonDetails {
readonly name: string;
age: number;
}
// make a new object that
// satisfies the PersonDetails interface
const johnDetails: PersonDetails = {
name: "John Doe",
age: 23,
};
// try to assign a new value to
// the read-only `name` property
// in the `johnDetails` object
johnDetails.name = "Lily John"; // ❌ Error. Cannot assign to 'name' because it is a read-only property.
For example, let's say we need to make an object to store a person's details where it needs to have 2 properties called name
and age
.
So first let's make an interface
called PersonDetails
and write the property names and the types it should hold.
It can be done like this,
// Object type declaration
interface PersonDetails {
name: string;
age: number;
}
Now we need to make the name
property read-only or immutable, to do that we can use the readonly
keyword before the property name in the PersonDetails
interface type declaration.
It can be done like this,
// Object type declaration
// where the name property is read-only
interface PersonDetails {
readonly name: string;
age: number;
}
After making the name
property as readonly
, let's now make an object called johnDetails
and use the PersonDetails
interface as its type like this,
// Object type declaration
// where the name property is read-only
interface PersonDetails {
readonly name: string;
age: number;
}
// make a new object that
// satisfies the PersonDetails interface
const johnDetails: PersonDetails = {
name: "John Doe",
age: 23,
};
Now that we have made the object, let's try to assign a new value to the read-only name
property in the johnDetails
object.
It can be done like this,
// Object type declaration
// where the name property is read-only
interface PersonDetails {
readonly name: string;
age: number;
}
// make a new object that
// satisfies the PersonDetails interface
const johnDetails: PersonDetails = {
name: "John Doe",
age: 23,
};
// try to assign a new value to
// the read-only `name` property
// in the `johnDetails` object
johnDetails.name = "Lily John"; // ❌ Error. Cannot assign to 'name' because it is a read-only property.
As you can see the TypeScript compiler doesn't allow assigning a new value to the read-only property name
and also shows us an error saying Cannot assign to 'name' because it is a read-only property
which is exactly what we want to happen.
We have successfully made the object property read-only or immutable. Yay 🥳!
See the above code live in codesandbox.
CAVEAT
If you have a nested object for the read-only object property, TypeScript doesn't show us an error when changing the object properties values inside the nested object.
TypeScript will only show the error if you are changing the value for the read-only object property itself.
For example, this is a valid code in TypeScript even though the otherDetails
property is a readonly
property.
// Object type declaration
// where the name and the otherDetails
// properties are read-only
interface PersonDetails {
readonly name: string;
age: number;
readonly otherDetails: { salary: number };
}
// make a new object that
// satisfies the PersonDetails interface
const johnDetails: PersonDetails = {
name: "John Doe",
age: 23,
otherDetails: {
salary: 50000,
},
};
johnDetails.otherDetails.salary = 40000; // ✅ Valid.
That's all 😃!