【问题标题】:Is it possible to use getters/setters in interface definition?是否可以在接口定义中使用 getter/setter?
【发布时间】: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 吗?

【问题讨论】:

    标签: interface get set accessor typescript


    【解决方案1】:

    可以在接口上指定属性,但不能强制是否使用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 中,它将在类函数内部定义,而不是扩展其原型对象。
    • 这似乎不适用于静态获取属性:/
    【解决方案2】:

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

    不推荐的做法;但一个选择。

    【讨论】:

      【解决方案3】:

      首先,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
      【解决方案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());
      

      请参阅TypeScript Playground 上的示例。

      【讨论】:

      • 根据最新的打字稿版本 4.3.2,这个答案是正确的。
      • 不完全是 OP 所要求的,而是 +1 显示接口如何在实现该接口的类中强制定义方法。
      猜你喜欢
      • 2021-06-19
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      相关资源
      最近更新 更多