typescript 是否可以在接口定义中使用 getter/setter?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12838248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 00:52:11  来源:igfitidea点击:

Is it possible to use getters/setters in interface definition?

interfacegetsetaccessortypescript

提问by Ivan Popov

At the moment, TypeScriptdoes not allow use get/set methods(accessors) in interfaces. For example:

目前,TypeScript不允许在接口中使用 get/set 方法(访问器)。例如:

interface I {
      get name():string;
}

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

furthermore, TypeScript does not allow use Array Function Expression in class methods: for ex.:

此外,TypeScript 不允许在类方法中使用数组函数表达式:例如:

class C {
    private _name:string;

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

Is there any other way I can use a getter and setter on an interface definition?

有没有其他方法可以在接口定义上使用 getter 和 setter?

回答by Fenton

You can specify the property on the interface, but you can't enforce whether getters and setters are used, like this:

您可以在接口上指定属性,但不能强制是否使用 getter 和 setter,如下所示:

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 this example, the interface doesn't force the class to use getters and setters, I could have used a property instead (example below) - but the interface is supposed to hide these implementation details anyway as it is a promise to the calling code about what it can call.

在这个例子中,接口不强制类使用 getter 和 setter,我可以使用一个属性来代替(下面的例子) - 但接口应该隐藏这些实现细节,因为它是对调用代码的承诺关于它可以调用什么。

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

And lastly, =>is not allowed for class methods - you could start a discussion on Codeplexif you think there is a burning use case for it. Here is an example:

最后,=>类方法是不允许的——如果你认为它有一个燃烧的用例,你可以开始关于 Codeplex 的讨论。下面是一个例子:

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

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

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

回答by Meirion Hughes

To supplement the other answers, if your desire is to define a get valueon an interface, you can use readonly:

为了补充其他答案,如果您希望get value在接口上定义 a ,您可以使用readonly

interface Foo {
  readonly value: number;
}

let foo: Foo = { value: 10 };

foo.value = 20; //error

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

but as far as I'm aware, and as others mentioned, there is no way currently to define a set-only property in the interface. You can, however, move the limitation to a run-time error (useful during the development cycle 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");
  }
}

Not recommended practice; but an option.

不推荐的做法;而是一种选择。

回答by Valentin

First of all, Typescript only supports getand setsyntax when targetting Ecmascript 5. To achieve this, you have to call the compiler with

首先,打字稿仅支持getset语法靶向的EcmaScript 5.要做到这一点的时候,你必须调用编译器

tsc --target ES5

Interfaces do not support getters and setters. To get your code to compile you would have to change it to

接口不支持 getter 和 setter。要让您的代码编译,您必须将其更改为

interface I { 
    getName():string;
}

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

What typescript does support is a special syntax for fields in constructors. In your case, you could have

typescript 支持的是构造函数中字段的特殊语法。在你的情况下,你可以有

interface I {
    getName():string;
}

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

Notice how class Cdoes not specify the field name. It is actually declared using syntactic sugar public name: stringin the constructor.

注意 classC没有指定 field name。它实际上是public name: string在构造函数中使用语法糖声明的。

As Sohnee points out, the interface is actually supposed to hide any implementation details. In my example, I have chosen the interface to require a java-style getter method. However, you can also a property and then let the class decide how to implement the interface.

正如 Sohnee 指出的那样,接口实际上应该隐藏任何实现细节。在我的示例中,我选择了需要 java 样式 getter 方法的接口。然而,你也可以一个属性然后让类决定如何实现接口。

回答by Hyman

Using TypeScript 3.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());

See example on TypeScript Playground.

请参阅TypeScript Playground上的示例。