How to remove the readonly modifier in typescript

How to remove the readonly modifier in typescript

ยท

3 min read

you've seen this types and interface or even classes that have a readonly modifier ๐Ÿ‘‡

interface Immutable {
  readonly name: string;
  readonly age: number;
  // so harsh
  readonly alive: boolean;
}

type Meme = {
  readonly funny: boolean;
}
class Test {
  constructor(public readonly name: string, public readonly age: number) {
    this.name = name;
    this.age = age;
  }
}

Now if you define an object according to the shape (or type) of the Immutable interface you can't change the value of the property like your normally would.

Pasted image 20220517120159.png

interface Immutable {
  readonly name: string;
  readonly age: number;
  readonly alive: boolean;
}

let person: Immutable = {
  age: 24,
  name: "daniel",
  alive: true // it's a matter of prespective
}

person.name = "Nigel";

And that's what we want, actually this is a normal behavior we want it to be readonly but the challenge is how we can write or better to say change the readonly property.

Here we can use Improve control over mapped type modifiers with help of index access types

Here is how we can remove readonly modifier from the last example.

Pasted image 20220517121354.png

interface Immutable {
  readonly name: string;
  readonly age: number;
  readonly alive: boolean;
}

let person: Immutable = {
  age: 24,
  name: "daniel",
  alive: true // it's a matter of prespective
}

person.name = "Nigel";


type Mutable = {
  -readonly [key in keyof Immutable]: Immutable[key];
}

let mut: Mutable = person;
// this is crazy
mut.name = "somethnig else";

As you can see in the picture, we define another type called Mutable. Then we remove the readonly modifier with the help of -readonly modifier (there is minus there -) from all of the Immutable key with mapped type and keyof operator

Also at the end of line we are adding all of the Immutable types (in this case string, number, boolean) with the help of index access types

So the example is intentional and i don't think somebody need at first to create an object with the shape of the Immutable which in this case is perons object then again add that to the new variable mut with the Mutable type.

But it shows that the Mutable type will indeed remove the readonly type. It's really cool ๐Ÿคฉ

Also you can do the same thing with class. here is an example ๐Ÿ‘‡

class Test {
  constructor(public readonly name: string, public readonly age: number) {
    this.name = name;
    this.age = age;
  }
}

let newTest = new Test("daniel", 23);
newTest.name = "something" // not possible
newTest.age = 100; // also not possible

type RemoveReadonly = {
  -readonly [key in keyof Test]: Test[key];
}

let removeReadonly: RemoveReadonly = newTest;
removeReadonly.name = "now i can do that";
removeReadonly.age = 100;

Hope it was useful. ๐Ÿค—