Search code examples
javascriptangulartypescriptreadonly-attribute

readonly properties and ngOnInit


Readonly properties can only be assigned in the constructor, but in angular it is discouraged and sometimes impossible to use the constructor for certain initialization and instead the angular hook ngOnInit is used. Is there any way to mark ngOnInit as a constructor with regard to the readonly attribute so that I can use readonly for essentially immutable properties that are only assigned a single time in ngOnInit?

edit: To clarify: im not looking for alternative ways to declare readonly properties. I want to declare them the regular way. Anything else I think would not be worth the tradeoff in readability just to get that static check. I was hoping there would be some annotation like there are for tslint to ignore the immutability inside ngOnInit.

From the answers so far I guess assigning them as (this as any).foo = bar; is the closest to what I would like to do, though I guess it's still uglier than just leaving out the readonly.


Solution

  • You can't mark a method as a constructor there is just no syntax for that. You can break the readonly which is just a compile time check by using a type assertion to any and access any public/private property you want in a type unsafe way. You can also use a mapped type to make the type mutable, but it only works for public properties:

    type Mutable<T> = { -readonly [ P in keyof T]: T[P] }
    
    class Foo {
        public readonly data: string;
        private readonly pdata: string;
        public init() {
            const ref: Mutable<this> = this;
            ref.data = "" 
            const pRef = this as any;
            pRef.pdata = ""
    
            const pSaferRef: { pdata: string } = this as any;
            pSaferRef.pdata = ""
        }
    }