Last updated: Feb 28, 2024
Reading timeยท3 min
The error "Cannot assign to 'X' because it is a read-only property" occurs when we try to change the value of a read-only property in a class or an object.
To solve the error, remove the readonly
modifier or use a type assertion to
change the value of the property.
Here is an example of how the error occurs when using classes.
// ๐๏ธ with classes class Employee { readonly country: string = 'Germany'; changeCountry() { // โ๏ธ Error: Cannot assign to 'country' because it is a read-only property.ts(2540) this.country = 'Chile'; } }
And here is an example of how the error occurs when using objects.
// ๐๏ธ with objects type Person = { readonly name: string; }; const obj: Person = { name: 'Bobby Hadz', }; // โ๏ธ Error: Cannot assign to 'name' because it is a read-only property.ts(2540) obj.name = 'Frank';
The examples use the readonly modifier to set the class and object properties to read-only which makes them immutable.
readonly
modifier if you have access to the codeTo solve the error, remove the readonly
modifier if you have access to the
code where it's set.
class Employee { country = 'Germany'; changeCountry() { this.country = 'Chile'; } } // ------------------------------------ type Person = { name: string; }; const obj: Person = { name: 'Bobby Hadz', }; obj.name = 'Frank';
If you can't remove the readonly
modifier but need to change the value of the
readonly
property, you can use a
type assertion.
class Employee { readonly country: string = 'Germany'; changeCountry() { (this.country as any) = 'Chile'; } } // ------------------------------------ type Person = { readonly name: string; }; const obj: Person = { name: 'Bobby Hadz', }; (obj.name as any) = 'Frank';
We used type assertions to cast the read-only properties to any
, to be able to
change their values.
You can also be more specific and cast the readonly
property to the type of
the value in the assignment.
class Employee { readonly country: string = 'Germany'; changeCountry() { (this.country as string) = 'Chile'; } } type Person = { readonly name: string; }; const obj: Person = { name: 'Bobby hadz', }; (obj.name as string) = 'Frank';
state
object.If that's the situation you're in, there is most likely a method, that the
library exports, which is used to mutate its state and it shouldn't be done
directly by changing the state
object.
I've also written a detailed article on how to change a readonly property to mutable.
If you need a class property that cannot be changed from the outside, and can
only be changed from within the class, set the property to protected
and use a
getter.
class Employee { protected _country = 'Germany'; get country(): string { return this._country; } changeCountry() { this._country = 'Chile'; } } const employee = new Employee(); console.log(employee.country); // ๐๏ธ "Germany" // โ๏ธ Cannot assign to 'country' because it is a read-only property.ts(2540) employee.country = 'Belgium';
Protected class properties can only be accessed from within the class and subclasses of the class.
That's why we added a getter that allows access from outside the class.
_country
property from the outside but they could call the changeCountry
method and set it to a specific property.You could also mark the changeCountry
method as protected or change the
_country
property from the class's constructor method. How you implement this
depends on your use case.
You can learn more about the related topics by checking out the following tutorials: