Cannot assign to read only property of Object in TypeScript

avatar

Borislav Hadzhiev

Last updated: Mar 15, 2022

banner

Photo from Unsplash

Cannot assign to read only property of Object in TypeScript #

The TypeScript error "Cannot assign to read only property of object" occurs when we try to change a property of a frozen object or when a property has been defined with Object.defineProperties(). To solve the error, create a copy of the object or array, or set the property to writable.

cannot assign to read only property ts

Here are three examples of how the error occurs.

index.ts
// 👇️ Frozen Object 👇️ const obj = { name: 'Tom', age: 30, }; Object.freeze(obj); // ⛔️ Error: Cannot assign to read only // property 'name' of object '#<Object>' obj.name = 'Bobby'; // 👇️ Frozen Array 👇️ const arr: string[] = ['one', 'two', 'three']; Object.freeze(arr); // ⛔️ Error: Cannot assign to read only // property '0' of object '[object Array]' arr[0] = 'four'; // 👇️ using Object.defineProperties() 👇️ const employee: { salary?: number } = {}; Object.defineProperties(employee, { salary: { value: 100, // writable: true, // 👈️ uncomment this }, }); // ⛔️ Error: Cannot assign to read only // property 'salary' of object '#<Object>' employee.salary = 300;

The first two examples show how the error occurs because the object or array has been frozen with the Object.freeze() method. A frozen object can no longer be changed, but you can create a copy of the array or object and change the copy.

index.ts
// 👇️ Frozen Object 👇️ const obj = { name: 'Tom', age: 30, }; Object.freeze(obj); const objCopy = { ...obj }; // 👈️ create copy of object objCopy.name = 'Bobby'; console.log(objCopy); // 👉️ {name: 'Bobby', age: 30} // 👇️ Frozen Array 👇️ const arr: string[] = ['one', 'two', 'three']; Object.freeze(arr); const arrCopy = [...arr]; // 👈️ create copy of array arrCopy[0] = 'four'; console.log(arrCopy); // 👉️ ['four', 'two', 'three']

We used the spread syntax (...) to create a copy of the object and array, so we can change them.

If you are using some third-party library that has frozen a state object or array, chances are you aren't supposed to be mutating the state object directly. The library probably exports a method that should be used to change the state.

If you are getting the error when using the Object.defineProperties method, you have to set the property as writable if you want to change its value.

index.ts
const employee: { salary?: number } = {}; Object.defineProperties(employee, { salary: { value: 100, writable: true, // 👈️ }, }); employee.salary = 300; console.log(employee.salary); // 👉️ 300

The salary property is set to writable, so it can be changed.

The writable property defaults to false when using the Object.defineProperties() method, so if you want to be able to change the value of a property, explicitly set writable to true.

If you pass an object or array to Object.freeze, you can't:

  • add new properties or elements to it
  • remove existing properties
  • change existing properties

The best way to get around this is create a copy of the object or array and change the copy.

Conclusion #

The TypeScript error "Cannot assign to read only property of object" occurs when we try to change a property of a frozen object or when a property has been defined with Object.defineProperties(). To solve the error, create a copy of the object or array, or set the property to writable.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.