Ist es möglich, Getter / Setter in TypeScript-Schnittstellen zu verwenden?


75

Ich möchte eine Schnittstelle mit einer schreibgeschützten Eigenschaft definieren. Zum Beispiel;

interface foo {
    get bar():bool;
}

Dies gibt jedoch den Syntaxfehler "erwartet ';'" in der Leiste an. Ich habe mein VisualStudio so eingerichtet, dass es das ES5-Ziel verwendet, sodass Getter unterstützt werden. Ist dies eine Einschränkung der Schnittstellen? Könnte diese Änderung in der Zukunft sein; Es ist eine sehr schöne Sache, das tun zu können.



2
Ja, dies ist eine Einschränkung der Schnittstellen. Siehe auch [diese Frage] [1]. [1]: stackoverflow.com/questions/12838248/…
Valentin

Antworten:


99

Nur-Getter-Eigenschaften wurden in Typescript 2.0 eingeführt :

interface foo {
    readonly bar: boolean;
}

6
Wenn ich mich nicht irre, erklärt dies immer noch barals Eigentum, nicht als Getter.
Alexander Abakumov

13
@AlexanderAbakumov the readonly gibt nicht an, dass es sich um eine Eigenschaft handeln muss. Da Eigenschaften wie Getter referenziert werden, kann die Klasse, die diese Schnittstelle implementiert, eine Eigenschaft oder einen Getter verwenden.
Nikeee

3
@nikeee: Ja, aber OP hat gefragt, ob wir Getter / Setter in Schnittstellen verwenden können, nicht in Eigenschaften.
Alexander Abakumov

4
@ AlexanderAbakumov, aber genau das ist es, ein Getter. Wenn Sie versuchen, der Eigenschaft zuzuweisen, erhalten Sie diesen FehlerError TS2540 (TS) Cannot assign to 'bar' because it is a constant or a read-only property.
Simon_Weaver

5
Das ist eine schreibgeschützte Eigenschaft, kein Getter. Es gibt einen kleinen Unterschied, wie hier gezeigt: property: readonly bar: boolean getter: get bar (): boolean {return a && b || c &&! e || (x | y | z)}
Rick O'Shea

21

Ja, dies ist eine Einschränkung der Schnittstellen. Ob der Zugriff auf die Eigenschaft mit einem Getter implementiert wird oder nicht, ist ein Implementierungsdetail und sollte daher nicht Teil der öffentlichen Schnittstelle sein. Siehe auch diese Frage .

Wenn Sie ein schreibgeschütztes Attribut benötigen, das in einer Schnittstelle angegeben ist, können Sie eine Getter-Methode hinzufügen:

interface foo {
    getAttribute() : string;
}

11
Leider ist es kein Implementierungsdetail, das schreibgeschützt ist. Ich wünschte, ich könnte das in Typoskript ausdrücken.
Ezward

Aha. Dann denke ich, dass Ihre einzige Möglichkeit darin besteht, eine Getter-Methode anzugeben. Ich habe meine Antwort entsprechend aktualisiert.
Valentin

2
Vermutlich wird dies in TypeScript 2.0 möglich sein: github.com/Microsoft/TypeScript/pull/6532
Michael Younkin

2

Wie @Vitaliy Ulantikov antwortete, können Sie den readonlyModifikator für eine Eigenschaft verwenden. Dies verhält sich genau wie ein Getter.

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

Wenn ein Objektliteral die Schnittstelle implementiert, können Sie eine readonlyEigenschaft nicht überschreiben :

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

Wenn eine Klasse die Schnittstelle implementiert, kann das Überschreiben nicht vermieden werden.

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!
    }
}

Ich denke, das liegt daran, dass beim erneuten Deklarieren von Eigenschaften in der Klassendefinition diese die Eigenschaften der Schnittstelle überschreiben und nicht mehr schreibgeschützt sind.

Um dies zu beheben, verwenden Sie readonlydie Eigenschaften direkt in der Klasse, die die Schnittstelle implementiert

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!
    }
}

Überzeugen Sie sich selbst auf dem Spielplatz .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.