Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typescript readonly property of class

Tags:

typescript

I noticed that typescript 2.0 will support readonly class properties, but it isn't available yet. The reason for this post is that I want to be smart about how I write my code today so that I can transition it with minimal pain later.

I want to use a class with readonly properties this way:

let widget = new Widget(110, 220); // width, height
//...
widget.width(200); // to modify the width, I use a setter with validation
widget.width = 300; // note: I want this to be a compile time error
//...
let w = widget.width; // and later I want to get/draw the current width

...but I can't get this to work due to fn and property having the same name - so I'll switch fn name to setWidth. I'd rather not prefix all my readonly properties with _ because in the past I've found that the pain is more than just the hassle of keying the extra character. And because of TS's type checking, I don't need the visual reminder that the property is readonly (or private).

Q1: Will the above work in typescript 2 if width is a readonly property of the widget class as below?

export class widget {
    readonly width:number;  // doesn't work in TS 1.8

    setWidth(w:number) {
        this.width = w;
    }
}

In the near term, I can either make the property public so I can access directly, with the 'risk' that I might set the property directly - or I can have private properties and write getters and setters.

Q2: If I do the latter, how much slower is the getter than direct property reference? Some of my properties will be called very frequently while dragging, so speed is important.

widget.getWidth();
// vs
widget.width;

UPDATE

I recently found this posted answer and realized that TS already supports most of what I was trying to do:

export class Widget {
    private _width:number;
    set width(w) {if (w >= 0) this._width = w}
    get width() {return this._width}
}

Usage syntax is same as for public property with no accessors, which is really nifty:

let widget = new Widget(...);
let existingWidth = widget.width;
widget.width = newWidth;

I'm hoping that TS2's readonly qualifier will give me direct read access to (private) properties (not through an accessor function, so faster), and none of my usage code will need to be changed. Anyone know?

like image 557
bedouger Avatar asked Mar 23 '16 15:03

bedouger


People also ask

How do you set a readonly property in TypeScript?

Readonly is a typescript keyword that makes the property read-only in a class, interface, or type alias. We make a property read-only by prefixing the property as readonly . We can assign a value to the readonly property only when initializing the object or within a constructor of the class.

How do I change a readonly value in TypeScript?

You can use mapping modifiers to change a readonly property to mutable in TypeScript, e.g. -readonly [Key in keyof Type]: Type[Key] . You can remove the readonly modifier by prefixing the readonly keyword with a minus - .

What is a readonly property?

The readOnly property sets or returns whether a text field is read-only, or not. A read-only field cannot be modified. However, a user can tab to it, highlight it, and copy the text from it.

What is private readonly?

If it's private and readonly , the benefit is that you can't inadvertently change it from another part of that class after it is initialized. The readonly modifier ensures the field can only be given a value during its initialization or in its class constructor.


1 Answers

Now that I'm using TS2, I've found that readonly is not what I want because the read-only restriction applies even inside the class. So the best I can come up with is using the private modifier and writing an explicit getter method. This is unfortunate for 2 reasons: speed of the read (presumably), and the getter method name must be different than the name of the private variable.

like image 85
bedouger Avatar answered Sep 29 '22 08:09

bedouger