Можно ли использовать геттеры/сеттеры в определении интерфейса?


на данный момент TypeScript не позволяет использовать методы get / set(методы доступа) в интерфейсах. Например:

interface I {
      get name():string;
}

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

кроме того, TypeScript не позволяет использовать выражение функции массива в методах класса: например.:

class C {
    private _name:string;

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

есть ли другой способ я могу использовать геттер и сеттер на определение интерфейса?

3 55

3 ответа:

вы можете указать свойство в интерфейсе, но вы не можете принудительно использовать геттеры и сеттеры, например:

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

в этом примере интерфейс не заставляет класс использовать геттеры и сеттеры, я мог бы использовать свойство вместо этого (пример ниже) - но интерфейс должен скрывать эти детали реализации в любом случае, поскольку это обещание вызывающему коду о том, что он может вызвать.

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

и наконец, => не допускается методы класса - вы могли бы начните обсуждение Codeplex если вы думаете, есть горящий вариант использования для этого. Вот пример:

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

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

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

чтобы дополнить другие ответы, если вы хотите определить get value на интерфейсе, вы можете сделать это:

interface Foo {
  readonly value: number;
}

let foo: Foo = { value: 10 };

foo.value = 20; //error

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

но насколько мне известно, и как уже упоминалось, в настоящее время нет способа определить свойство только для набора в интерфейсе. Однако вы можете переместить ограничение на ошибку времени выполнения (полезно только во время цикла разработки):

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

не рекомендуется; а вариант.

во-первых, Typescript поддерживает только get и set синтаксис при таргетинге Ecmascript 5. Для этого необходимо вызвать компилятор с помощью

tsc --target ES5

интерфейсы не поддерживают геттеры и сеттеры. Чтобы получить код для компиляции вам придется изменить его на

interface I { 
    getName():string;
}

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

что поддерживает typescript-это специальный синтаксис для полей в конструкторах. В вашем случае, вы могли бы

interface I {
    getName():string;
}

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

обратите внимание, как класс C не указано поле name. Он фактически объявлен с использованием синтаксического сахара public name: string в конструкторе.

как указывает Sohnee, интерфейс на самом деле должен скрывать любые детали реализации. В моем примере я выбрал интерфейс, требующий метода getter в стиле java. Однако вы также можете создать свойство, а затем позволить классу решить, как реализовать интерфейс.