Change a readonly property to mutable in TypeScript

avatar
Borislav Hadzhiev

Last updated: Feb 28, 2024
2 min

banner

# Change a readonly property to mutable in TypeScript

You can use mapping modifiers to change a readonly property to mutable in TypeScript.

You can remove the readonly modifier by prefixing the readonly keyword with a minus -.

Here is an example when working with classes.

index.ts
// โœ… With Classes class Employee { constructor(public readonly name: string) { this.name = name; } } // ๐Ÿ‘‡๏ธ create utility type type Mutable<Type> = { -readonly [Key in keyof Type]: Type[Key]; }; const emp: Mutable<Employee> = new Employee('Bobby Hadz'); emp.name = 'Alice'; console.log(emp.name); // ๐Ÿ‘‰๏ธ 'Alice'

change readonly property to mutable in typescript

The code for this article is available on GitHub

And here is an example when working with objects.

index.ts
// โœ… With Objects interface Person { readonly country: string; } // ๐Ÿ‘‡๏ธ create utility type type Mutable<Type> = { -readonly [Key in keyof Type]: Type[Key]; }; const obj: Mutable<Person> = { country: 'Germany', }; obj.country = 'Austria'; console.log(obj); // ๐Ÿ‘‰๏ธ {country: 'Austria'}

example when working with objects

We created a Mutable utility type that uses mapping modifiers to make properties in a class or object mutable.

Mapping modifiers are removed or added by prefixing them with a plus + or minus -. If you don't explicitly add a prefix, then + is assumed.

The type basically removes readonly attributes from a type's properties.

index.ts
type Mutable<Type> = { -readonly [Key in keyof Type]: Type[Key]; }; type Address = { readonly country: string; readonly city: string; }; // ๐Ÿ‘‡๏ธ type MutableAddress = { // country: string; // city: string; // } type MutableAddress = Mutable<Address>;

# Using a type assertion to cast the type to mutable

You can also use a type assertion to cast the type of the object to mutable.

index.ts
// โœ… With Classes class Employee { constructor(public readonly name: string) { this.name = name; } } type Mutable<Type> = { -readonly [Key in keyof Type]: Type[Key]; }; // ๐Ÿ‘‡๏ธ using a type assertion const emp = new Employee('Bobby Hadz') as Mutable<Employee>; emp.name = 'Alice'; console.log(emp.name); // ๐Ÿ‘‰๏ธ 'Alice'

using type assertion to cast the type to mutable

The code for this article is available on GitHub

And here is an example when working with objects.

index.ts
interface Person { readonly country: string; } type Mutable<Type> = { -readonly [Key in keyof Type]: Type[Key]; }; // ๐Ÿ‘‡๏ธ using type assertion const obj = { country: 'Germany', } as Mutable<Person>; obj.country = 'Austria'; console.log(obj); // ๐Ÿ‘‰๏ธ {country: 'Austria'}

You might also have to do as unknown as Mutable<MyType> if your types diverge.

# Using the any type

If you don't like any of the approaches, you can also cast the object to any before changing its property. This would suppress all type-checking errors.

index.ts
class Employee { constructor(public readonly name: string) { this.name = name; this.country = country; } } const emp1 = new Employee('Bobby Hadz'); // โ›”๏ธ Error: Cannot assign to 'name' because it is a read-only property.ts(2540) emp1.name = 'Alice'; // โœ… Works without errors (emp1 as any).name = 'Alice'; console.log(emp1.name); // ๐Ÿ‘‰๏ธ "Alice"

I prefer to use the any type sparingly because it effectively turns off type checking.

However, when you need a quick and dirty solution, it gets the job done.

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.

Copyright ยฉ 2024 Borislav Hadzhiev