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

Posted

技术标签:

【中文标题】是否可以在接口定义中使用 getter/setter?【英文标题】:Is it possible to use getters/setters in interface definition? 【发布时间】:2012-10-02 00:57:53 【问题描述】:

目前,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;

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

【问题讨论】:

【参考方案1】:

为了补充其他答案,如果您希望在接口上定义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】:

使用 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 上的示例。

【讨论】:

根据最新的打字稿版本 4.3.2,这个答案是正确的。 不完全是 OP 所要求的,而是 +1 显示接口如何在实现该接口的类中强制定义方法。【参考方案3】:

可以在接口上指定属性,但不能强制是否使用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);

在这个例子中,接口不强制类使用 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);

最后,=> 不允许用于类方法 - 如果你认为它有一个燃烧的用例,你可以 start a discussion on Codeplex。这是一个例子:

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

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

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

【讨论】:

您可以使用=> 来定义这样的类方法:name = (a: string) => this._name; 但在输出 JS 中,它将在类函数内部定义,而不是扩展其原型对象。 这似乎不适用于静态获取属性:/【参考方案4】:

首先,Typescript 在面向 Ecmascript 5 时仅支持 getset 语法。要实现这一点,您必须调用编译器

tsc --target ES5

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

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 指出的那样,接口实际上应该隐藏任何实现细节。在我的示例中,我选择了需要 java 风格的 getter 方法的接口。但是,您也可以一个属性,然后让类决定如何实现接口。

【讨论】:

您可以在 TypeScript 中使用 getset 关键字。 关于 ECMAScript 5 支持的附注 - Object.defineProperty 在 IE8+、FF4+、Opera 12+、WebKit 和 Safari 中受支持。 github.com/kriskowal/es5-shim 上还有一个 EC5 Shim

以上是关于是否可以在接口定义中使用 getter/setter?的主要内容,如果未能解决你的问题,请参考以下文章

java集合进行排序的两种方式

Lombok 写一个@Data更好还是@Getter+@Setter更好?

ImageView显示图像控件

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

是否可以在 prisma 中定义接口?

是否可以在接口中实现本机方法?