Чи можна використовувати геттери / сеттери у визначенні інтерфейсу?


93

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

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

Чи є інший спосіб використовувати геттер та сеттер у визначенні інтерфейсу?

Відповіді:


126

Ви можете вказати властивість на інтерфейсі, але ви не можете встановити, чи використовуються геттери та сетери, наприклад:

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';
}

1
Ви можете використовувати =>для визначення методів класу, як це: name = (a: string) => this._name;але у вихідному JS це буде визначено всередині функції класу, а не розширюватиме його об'єкт-прототип.
орад

здається, це не працює зі статичними властивостями get: /
CervEd

46

Щоб доповнити інші відповіді, якщо ви бажаєте визначити get valueінтерфейс, ви можете використовувати readonly:

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

Не рекомендується практика ; але варіант.


2

Перш за все, Машинопис тільки підтримує getі setсинтаксис , коли орієнтується ECMAScript 5. Для досягнення цієї мети, ви повинні викликати компілятор з

tsc --target ES5

Інтерфейси не підтримують геттери та сетери. Щоб ваш код скомпілювався, вам доведеться змінити його на

interface I { 
    getName():string;
}

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

Те, що підтримує машинопис, - це спеціальний синтаксис полів у конструкторах. У вашому випадку ви могли б

interface I {
    getName():string;
}

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

Зверніть увагу, як клас Cне вказує поле name. Він фактично оголошений із використанням синтаксичного цукру public name: stringв конструкторі.

Як зазначає Соні, інтерфейс насправді повинен приховувати будь-які деталі реалізації. У своєму прикладі я вибрав інтерфейс, щоб вимагати метод отримання в стилі Java. Однак ви також можете властивість, а потім дозволити класу вирішити, як реалізувати інтерфейс.


1
Ви можете використовувати ключові слова getта setключові слова в TypeScript.
Фентон,

Побічна примітка щодо підтримки ECMAScript 5 - Object.definePropertyпідтримується в IE8 +, FF4 +, Opera 12+, WebKit та Safari. Існує також шина EC5
Фентон

-1

Використання 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());

Див. Приклад на TypeScript Playground .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.