Ist es möglich, Getter / Setter in der Schnittstellendefinition zu verwenden?


91

Derzeit ist die TypeScriptVerwendung von get / set-Methoden (Accessoren) in Schnittstellen nicht zulässig. Beispielsweise:

interface I {
      get name():string;
}

class C implements I {
      get name():string {
          return null;
      } 
}

Darüber hinaus erlaubt TypeScript nicht die Verwendung von Array-Funktionsausdrücken in Klassenmethoden: zum Beispiel:

class C {
    private _name:string;

    get name():string => this._name;
}

Gibt es eine andere Möglichkeit, einen Getter und Setter für eine Schnittstellendefinition zu verwenden?

Antworten:


125

Sie können die Eigenschaft auf der Schnittstelle angeben, aber Sie können nicht erzwingen, ob Getter und Setter wie folgt verwendet werden:

interface IExample {
    Name: string;
}

class Example implements IExample {
    private _name: string = "Bob";

    public get Name() {
        return this._name;
    }

    public set Name(value) {
        this._name = value;
    }
}

var example = new Example();
alert(example.Name);

In diesem Beispiel zwingt die Schnittstelle die Klasse nicht dazu, Getter und Setter zu verwenden. Ich hätte stattdessen eine Eigenschaft verwenden können (Beispiel unten) - aber die Schnittstelle soll diese Implementierungsdetails trotzdem verbergen, da dies ein Versprechen für den aufrufenden Code ist darüber, was es nennen kann.

interface IExample {
    Name: string;
}

class Example implements IExample {
    // this satisfies the interface just the same
    public Name: string = "Bob";
}

var example = new Example();
alert(example.Name);

Und schließlich =>ist dies für Klassenmethoden nicht zulässig. Sie können eine Diskussion über Codeplex beginnen, wenn Sie der Meinung sind, dass es einen brennenden Anwendungsfall dafür gibt. Hier ist ein Beispiel:

class Test {
    // Yes
    getName = () => 'Steve';

    // No
    getName() => 'Steve';

    // No
    get name() => 'Steve';
}

1
Sie können =>Klassenmethoden wie name = (a: string) => this._name;folgt definieren : In der Ausgabe JS wird sie jedoch innerhalb der Klassenfunktion definiert, anstatt das Prototypobjekt zu erweitern.
— Orad

43

Um die anderen Antworten zu ergänzen, können Sie Folgendes verwenden, wenn Sie eine get valueauf einer Schnittstelle definieren möchten readonly:

interface Foo {
  readonly value: number;
}

let foo: Foo = { value: 10 };

foo.value = 20; //error

class Bar implements Foo {
  get value() {
    return 10;
  }
}

Soweit mir bekannt ist und wie bereits erwähnt, gibt es derzeit keine Möglichkeit, eine Set-Only-Eigenschaft in der Schnittstelle zu definieren. Sie können die Beschränkung jedoch auf einen Laufzeitfehler verschieben (nur während des Entwicklungszyklus nützlich):

interface Foo {
  /* Set Only! */
  value: number;
}

class Bar implements Foo {
  _value:number;
  set value(value: number) {
    this._value = value;
  }
  get value() {
    throw Error("Not Supported Exception");
  }
}

Nicht empfohlene Übung ; aber eine Option.


2

Zunächst einmal unterstützt Typescript getund setSyntax nur, wenn es auf Ecmascript 5 abzielt. Um dies zu erreichen, müssen Sie den Compiler mit aufrufen

tsc --target ES5

Schnittstellen unterstützen keine Getter und Setter. Um Ihren Code zum Kompilieren zu bringen, müssten Sie ihn in ändern

interface I { 
    getName():string;
}

class C implements I { 
    getName():string {
          return null;
    }   
}

Was Typoskript unterstützt, ist eine spezielle Syntax für Felder in Konstruktoren. In Ihrem Fall könnten Sie haben

interface I {
    getName():string;
}

class C implements I {
    constructor(public name: string) {
    }
    getName():string {
        return name;
    }
}

Beachten Sie, dass die Klasse Cdas Feld nicht angibt name. Es wird tatsächlich mit syntaktischem Zucker public name: stringim Konstruktor deklariert .

Wie Sohnee betont, soll die Schnittstelle tatsächlich alle Implementierungsdetails verbergen. In meinem Beispiel habe ich die Schnittstelle so ausgewählt, dass eine Getter-Methode im Java-Stil erforderlich ist. Sie können jedoch auch eine Eigenschaft festlegen und dann die Klasse entscheiden lassen, wie die Schnittstelle implementiert werden soll.


1
Sie können getund setSchlüsselwörter in TypeScript verwenden.
— Fenton

Eine Randnotiz zur Unterstützung von ECMAScript 5 - Object.definePropertywird in IE8 +, FF4 +, Opera 12+, WebKit und Safari unterstützt. Es gibt auch eine EC5 Shim unter github.com/kriskowal/es5-shim
— Fenton

-1

Verwenden von TypeScript 3.4:

interface IPart {
    getQuantity(): number;
}

class Part implements IPart {
    private quantity: number;
    constructor(quantity: number) {
        this.quantity = quantity;
    }
    public getQuantity = (): number => {
        return this.quantity;
    };
}

let part = new Part(42);

// When used in typescript, quantity is not accessible.
// However, when compiled to javascript it will log '42'.
console.log(part.quantity);

// Logs '42'.
console.log(part.getQuantity());

Siehe Beispiel auf TypeScript Playground .

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.