Assign value to `readonly` properties from methods called by the constructor

18,398

Solution 1

I usually use this workaround.

  private _myValue = true
  get myValue (): boolean { return this._myValue }

Now you can change the property from within the class and the property is readonly from the outside. One advantage of this workaround is that you can refactor your property names without generating errors. That's why I wouldn't use something like this (this as any).readOnlyProperty = raw.

Solution 2

Instead of "casting" this as any, you can still enforce type checking by modifying just this property:

(this.readOnlyProperty as string) = raw; // OK
(this.readOnlyProperty as string) = 5;   // TS2322: Type '5' is not assignable to type 'string'.

Solution 3

When you create a separate function to assign the value, this separate function can be used from somewhere else than the sole constructor. The compiler will not check (and for a public function, will not even be able to check) that the function is only called from constructor. So the error.

You have 2 workarounds to assign the value anyway. The cleaner would be to put the core of your separate function into the constructor. The other one, which will make you loose the type checking and so is not recommanded unless you really know what you are doing would be to convert this into any:

(this as any).readOnlyProperty = raw
Share:
18,398

Related videos on Youtube

Bill
Author by

Bill

Updated on September 16, 2022

Comments

  • Bill
    Bill over 1 year

    I have a simple class, and I want to assign a value to a readonly property in a method initiated by the constructor, but it says [ts] Cannot assign to 'readOnlyProperty' because it is a constant or a read-only property. Why can't I assign a value to the property even though I am calling process from the constructor?

    Sample Code:

    class C {
        readonly readOnlyProperty: string;
        constructor(raw: string) {
            this.process(raw);
        }
        process(raw: string) {
            this.readOnlyProperty = raw; // [ts] Cannot assign to 'readOnlyProperty' because it is a constant or a read-only property.
        }
    }
    
    • Robby Cornelissen
      Robby Cornelissen over 5 years
      How is the TypeScript compiler supposed to infer that process() will only ever be called from the constructor?
  • tru7
    tru7 about 4 years
    I think this is the cleanest most efficient answer