Is it possible to use a readonly property in TypeScript Interfaces?

Typescript

Typescript Problem Overview


I would like to define an interface with a readonly property. For instance;

interface foo {
    get bar():bool;
}

However, this gives the syntax error, "expected ';'" on bar. I have setup my VisualStudio to use the ES5 target, so getters are supported. Is this a limitation of interfaces? Might this change in the future; it is a very nice thing to be able to do.

Typescript Solutions


Solution 1 - Typescript

Getter-only properties were introduced in Typescript 2.0:

interface foo {
    readonly bar: boolean;
}

Solution 2 - Typescript

Yes, this is a limitation of interfaces. Whether or not the access to the property is implemented with a getter is an implementation detail and thus should not be part of the public interface. See also this question.

If you need a readonly attribute specified in an interface, you can add a getter method:

interface foo {
    getAttribute() : string;
}

Solution 3 - Typescript

As @Vitaliy Ulantikov answered, you may use the readonly modifier on a property. This acts exactly like a getter.

interface Point {
    readonly x: number;
    readonly y: number;
}

When an object literal implements the interface, you cannot overwrite a readonly property:

let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!

But when a class implements the interface, there is no way to avoid overwriting it.

class PointClassBroken implements Point {
    // these are required in order to implement correctly
    x: number;
    y: number;

    constructor(x: number, y: number) {
        this.x = x
        this.y = y
    }

    changeCoordinates(x: number, y: number): void {
        this.x = x // no error!
        this.y = y // no error!
    }
}

I guess that’s because when you re-declare properties in the class definition, they override the properties of the interface, and are no longer readonly.

To fix that, use readonly on the properties directly in the class that implements the interface

class PointClassFixed implements Point {
    readonly x: number;
    readonly y: number;

    constructor(x: number, y: number) {
        this.x = x
        this.y = y
    }

    changeCoordinates(x: number, y: number): void {
        this.x = x // error!
        this.y = y // error!
    }
}

See for yourself in the playground.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEzwardView Question on Stackoverflow
Solution 1 - TypescriptVitaliy UlantikovView Answer on Stackoverflow
Solution 2 - TypescriptValentinView Answer on Stackoverflow
Solution 3 - TypescriptchharveyView Answer on Stackoverflow