È possibile utilizzare getter / setter nella definizione dell'interfaccia?


93

Al momento, TypeScriptnon consente l'uso di metodi get / set (accessors) nelle interfacce. Per esempio:

interface I {
      get name():string;
}

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

inoltre, TypeScript non consente l'uso dell'espressione della funzione array nei metodi di classe: ad es .:

class C {
    private _name:string;

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

C'è un altro modo per utilizzare un getter e un setter sulla definizione di un'interfaccia?

Risposte:


125

È possibile specificare la proprietà sull'interfaccia, ma non è possibile imporre se vengono utilizzati getter e setter, in questo modo:

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 questo esempio, l'interfaccia non forza la classe a utilizzare getter e setter, avrei potuto invece usare una proprietà (esempio sotto) - ma l'interfaccia dovrebbe nascondere comunque questi dettagli di implementazione in quanto è una promessa al codice chiamante su cosa può chiamare.

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);

Infine, =>non è consentito l'uso dei metodi di classe: potresti iniziare una discussione su Codeplex se pensi che ci sia un caso d'uso scottante per questo. Ecco un esempio:

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

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

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

1
Puoi usare =>per definire metodi di classe come questo: name = (a: string) => this._name;ma nell'output JS sarà definito all'interno della funzione di classe piuttosto che estendere il suo oggetto prototipo.
orad

44

Per integrare le altre risposte, se il tuo desiderio è definire un get valuesu un'interfaccia, puoi utilizzare readonly:

interface Foo {
  readonly value: number;
}

let foo: Foo = { value: 10 };

foo.value = 20; //error

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

ma per quanto ne so, e come altri menzionati, non c'è attualmente alcun modo per definire una proprietà di solo set nell'interfaccia. È tuttavia possibile spostare la limitazione in un errore di runtime (utile solo durante il ciclo di sviluppo):

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");
  }
}

Pratica non consigliata ; ma un'opzione.


2

Prima di tutto, Carattere tipografico supporta solo gete setsintassi quando rivolte a ECMAScript 5. Per raggiungere questo obiettivo, è necessario chiamare il compilatore con

tsc --target ES5

Le interfacce non supportano getter e setter. Per fare in modo che il tuo codice si compili, dovresti cambiarlo in

interface I { 
    getName():string;
}

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

Ciò che il dattiloscritto supporta è una sintassi speciale per i campi nei costruttori. Nel tuo caso, potresti avere

interface I {
    getName():string;
}

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

Nota come la classe Cnon specifica il campo name. In realtà è dichiarato utilizzando lo zucchero sintattico public name: stringnel costruttore.

Come sottolinea Sohnee, l'interfaccia dovrebbe effettivamente nascondere tutti i dettagli di implementazione. Nel mio esempio, ho scelto l'interfaccia per richiedere un metodo getter in stile java. Tuttavia, puoi anche una proprietà e lasciare che sia la classe a decidere come implementare l'interfaccia.


1
È possibile utilizzare gete setparole chiave in TypeScript.
Fenton

Una nota a margine sul supporto ECMAScript 5 - Object.definePropertyè supportato in IE8 +, FF4 +, Opera 12+, WebKit e Safari. C'è anche un EC5 Shim su github.com/kriskowal/es5-shim
Fenton

-1

Utilizzando 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());

Vedi esempio su TypeScript Playground .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.