Можно ли использовать геттеры/сеттеры в определении интерфейса?
В настоящий момент TypeScript
не позволяет использовать методы get/set (accessors) в интерфейсах.
Например:
interface I {
get name():string;
}
class C implements I {
get name():string {
return null;
}
}
кроме того, TypeScript не позволяет использовать выражение класса Array в методах класса:
например:
class C {
private _name:string;
get name():string => this._name;
}
Есть ли другой способ использования getter и setter в определении интерфейса?
Ответы
Ответ 1
Вы можете указать свойство на интерфейсе, но вы не можете обеспечить, используются ли геттеры и сеттеры, например:
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';
}
Ответ 2
В дополнение к другим ответам, если вы хотите определить get value
на интерфейсе, вы можете сделать это:
interface Foo {
readonly value: number;
}
let foo: Foo = { value: 10 };
foo.value = 20; //error
class Bar implements Foo {
get value() {
return 10;
}
}
но, насколько мне известно, и, как упоминалось в других публикациях, в настоящее время нет способа определить свойство set-only в интерфейсе. Однако вы можете переместить ограничение на ошибку во время выполнения (полезно только во время цикла разработки):
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");
}
}
Не рекомендуется практика; но вариант.
Ответ 3
Во-первых, 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. Однако вы также можете использовать свойство, а затем позволить классу решить, как реализовать интерфейс.
Ответ 4
Используя 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());
Смотрите пример на {
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()); rel="nofollow noreferrer">TypeScript Playground.