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

前端 未结 4 845
青春惊慌失措
青春惊慌失措 2020-12-14 14:01

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

interface I {
      get name():string;
}

cl         


        
相关标签:
4条回答
  • 2020-12-14 14:14

    To supplement the other answers, if your desire is to define a get value on an interface, you can use 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.

    0 讨论(0)
  • 2020-12-14 14:23

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

    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.

    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 Codeplex if you think there is a burning use case for it. Here is an example:

    class Test {
        // Yes
        getName = () => 'Steve';
    
        // No
        getName() => 'Steve';
    
        // No
        get name() => 'Steve';
    }
    
    0 讨论(0)
  • 2020-12-14 14:27

    Using 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.

    0 讨论(0)
  • 2020-12-14 14:32

    First of all, Typescript only supports get and set syntax when targetting Ecmascript 5. To achieve this, you have to call the compiler with

    tsc --target ES5
    

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

    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

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

    Notice how class C does not specify the field name. It is actually declared using syntactic sugar public name: string in the constructor.

    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.

    0 讨论(0)
提交回复
热议问题