É possível usar getters / setters na definição da interface?


93

No momento, TypeScriptnão permite o uso de métodos get / set (acessores) em interfaces. Por exemplo:

interface I {
      get name():string;
}

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

além disso, o TypeScript não permite o uso de Array Function Expression em métodos de classe: por exemplo:

class C {
    private _name:string;

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

Existe alguma outra maneira de usar um getter e setter em uma definição de interface?

Respostas:


125

Você pode especificar a propriedade na interface, mas não pode impor se getters e setters são usados, como este:

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

Neste exemplo, a interface não força a classe a usar getters e setters, eu poderia ter usado uma propriedade (exemplo abaixo) - mas a interface deve ocultar esses detalhes de implementação de qualquer maneira, pois é uma promessa para o código de chamada sobre o que pode chamar.

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

E, por último, =>não é permitido para métodos de classe - você pode iniciar uma discussão no Codeplex se achar que há um caso de uso ardente para ele. Aqui está um exemplo:

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

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

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

1
Você pode usar =>para definir métodos de classe como este: name = (a: string) => this._name;mas no JS de saída, ele será definido dentro da função de classe em vez de estender seu objeto de protótipo.
— orad

44

Para complementar as outras respostas, se seu desejo é definir um get valueem uma interface, você pode usar readonly:

interface Foo {
  readonly value: number;
}

let foo: Foo = { value: 10 };

foo.value = 20; //error

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

mas, tanto quanto eu sei, e como outros mencionaram, não há nenhuma maneira atualmente de definir uma propriedade apenas de conjunto na interface. Você pode, no entanto, mover a limitação para um erro de tempo de execução (útil apenas durante o ciclo de desenvolvimento):

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

Prática não recomendada ; mas uma opção.


2

Primeiro de tudo, Typescript só suporta gete setsintaxe quando targetting ECMAScript 5. Para conseguir isso, você tem que chamar o compilador com

tsc --target ES5

As interfaces não oferecem suporte a getters e setters. Para obter o seu código para compilar, você teria que alterá-lo para

interface I { 
    getName():string;
}

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

O que o typescript suporta é uma sintaxe especial para campos em construtores. No seu caso, você poderia ter

interface I {
    getName():string;
}

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

Observe como a classe Cnão especifica o campo name. Na verdade, é declarado usando açúcar sintático public name: stringno construtor.

Como Sohnee aponta, a interface deve, na verdade, ocultar quaisquer detalhes de implementação. No meu exemplo, escolhi a interface para exigir um método getter no estilo java. No entanto, você também pode definir uma propriedade e deixar a classe decidir como implementar a interface.


1
Você pode usar palavras get- setchave e no TypeScript.
— Fenton

Uma nota lateral sobre o suporte ECMAScript 5 - Object.definePropertyé compatível com IE8 +, FF4 +, Opera 12+, WebKit e Safari. Há também um EC5 Shim em github.com/kriskowal/es5-shim
— Fenton

-1

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

Veja o exemplo em TypeScript Playground .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.