Cannot Assign to Read Only Property of String

The "readonly" lie of Typescript

"I'm non upset that y'all lied to me, I'm upset that from now on I can't believe y'all." ― Friedrich Nietzsche

Meet Baton.

He is a programmer just starting with Typescript, working on a new projection excited and full of hope for a improve future.

He is learning equally much as he can while working on a project that makes use of this new linguistic communication.

One thing to know nearly Billy is that he really cares well-nigh type safety and also almost immutability.

For example, he would like to ascertain a structure belongings user data. Permit's say the user has a proper noun, a telephone number, and an address.

              interface UserInfo {     name : cord,     telephone: cord,     address: string }                          

Being a fan of immutability, he wants to make sure that if he creates an case of this object, information technology won't be modified later.

A first attempt

He first comes across the const modifier that can be specified when declaring a variable. Hmm, maybe that works?

              const user : UserInfo = { 	proper name : "Bruce", 	Telephone : "3334444", 	Address : "World" }  user = { 	name : "Peter", 	phone : "1234567", 	address : "Moon" }  //fails with the error: cannot assign to 'user' considering it is a constant  //no complaints user.name = "Peter" user.phone = "1234567" user.address = "Moon"                          

It turns out this doesn't do what he wants. This just makes the reference immutable, simply the referent can still be modified:

Making progress

Billy is perseverant and he finds a new low-cal: the readonly modifier. This is like const, only for properties. And then at present he can redefine the UserInfo interface:

              interface UserInfo {     readonly name : string,     readonly phone: cord,     readonly address: string }  const user : UserInfo = { 	name : "Bruce", 	phone : "3334444", 	address : "World" }    user.proper name = "Peter" // this one fails now since the belongings was marked as readonly: cannot assign to 'name' because it is a read-only property user.phone = "1234567" // likewise fails user.accost = "Moon" // also fails                          

Third time is the charm

Dainty! But he doesn't want to impose immutability on anybody that would want to make apply of the UserInfo interface. Here he discovers the Readonly<Type> construct. This accepts a blazon and returns a type with all the properties of the input type equally if they would have the readonly modifier set.

              interface userInfo {     name : cord,      phone: string,     accost: string }  const immutableUserInfo : Readonly<UserInfo> = { 	proper noun : "Bruce", 	telephone :"3334444", 	address :"Earth" }   const mutableUserInfo : UserInfo = { 	proper name : "Peter", 	telephone :"1234567", 	address :"Moon" }   immutableUserInfo.name = "Alfred" //fails with the mistake: cannot assign to 'name' considering it is a read-but property  mutableUserInfo.proper noun = "Alfred" //works                          

Dainty! At present Billy and anybody else can be happy, each making use of UserInfo as they meet fit.

Or is it?

Later on on in the project, he wants to check that the data in a UserInfo object is correct. For that purpose, he makes use of a library delivered by some of his colleagues that provides the following innocent-looking function:

              office checkUserInfo(userInfo : UserInfo);                          

What he doesn't know is that checkUserInfo not simply does it bank check the user info, but too tries to sanitize it(e.thou. it removes special characters from the name), so it tries to change the input data. In our case, it will merely straight upward supplant the value of the 'name' property on the input object.

Billy doesn't demand or want that for his use case, but the function is poorly documented and then he has no idea that this function will modify his input information and for some cases, it volition result in corrupted information.

Just in that location is no reason to worry, to make sure things are going to exist ok he passes a readonly blazon as an statement. Surely the compiler will save Billy.

                              function checkUserInfo(userInfo : UserInfo):void{         userInfo.proper name = "default"; }  const immutableUserInfo : Readonly<UserInfo> = { 	name : "Bruce", 	phone : "3334444", 	address : "Earth" }    checkUserInfo(immutableUserInfo); //no compiler mistake/alarm!!?                          

Expect a minute, information technology seems like there is no ane to save Billy hither!

He specified an immutable argument and the part modified it with no issues raised by the compiler.

What is happening here?

The LIE!

Well if nosotros look at the signature, the function definition specifies the mutable version of the interface. To keep the type promise of immutability for our immutableUserInfo variable there are at least ii options:

  • the compiler should warn us that the function is modifying the input,
  • a lot more straightforward, it should complain virtually any calls like this, where the part is being chosen with an immutable variable when the type in the definition is a mutable one.

It turns out Typescript doesn't do any of those and does non keep the promise of blazon condom, assuasive readonly types to be assigned to mutable types. More than that, it is a deliberate conclusion in gild to take some backward compatibility.

Hope and a lifeline

There are several issues raised on Github about this(e.1000. 13002, 13347), beingness open for several years already, but information technology seems there is no real progress taking place. If you would like this to be fixed somewhere in the most future, make sure to have your vox heard on those issues.

In the meantime, not all promise is lost. There is one possible solution under the grade of an ESLint dominion. It tin can exist found in this repo: eslint-plugin-total-functions, and the rule you lot are looking for is no-dangerous-readonly-mutable-assignment which is also part of the plugin'southward recommended rules.

If there are other quirks like this of Typescript that y'all know off let me know in the comments.

chabrillanannothing.blogspot.com

Source: https://www.banterly.net/2021/08/20/the-readonly-lie-of-typescript/

0 Response to "Cannot Assign to Read Only Property of String"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel