2012-10-11 56 views
47

Por el momento, TypeScript no permite el uso de métodos get/set (accessors) en las interfaces. Por ejemplo:¿Es posible usar getters/setters en la definición de interfaz?

interface I { 
     get name():string; 
} 

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

además, mecanografiado no permite el uso de expresiones de matriz de funciones en los métodos de clase: por ej .:

class C { 
    private _name:string; 

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

¿Hay alguna otra manera de que pueda utilizar un getter y setter de una definición de interfaz?

Respuesta

64

Puede especificar la propiedad en la interfaz, pero no se puede cumplir si se utilizan captadores y definidores, así:

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

En este ejemplo, la interfaz no obliga a la clase que se utiliza getters y setters, podría haber usado una propiedad en su lugar (ejemplo a continuación), pero la interfaz se supone que oculta estos detalles de implementación de todos modos, ya que es una promesa para el código de llamada sobre lo que puede llamar.

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

Y, por último, => no está permitido para los métodos de la clase - que podría start a discussion on Codeplex si le parece que es un caso de uso de leña para ella. He aquí un ejemplo:

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

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

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

Puede usar '=>' para definir métodos de clase como este: 'name = (a: string) => this._name;' pero en la salida JS se definirá dentro de la función de clase en lugar de extender su objeto prototipo. – orad

3

En primer lugar, Letra de imprenta sólo es compatible con get y set sintaxis al que apuntan a ECMAScript 5. Para lograr esto, usted tiene que llamar al compilador con

tsc --target ES5 

interfaces no son compatibles con los captadores y definidores. Para obtener su código para compilar tendría que cambiarlo a

interface I { 
    getName():string; 
} 

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

Lo que hace mecanografiado apoyo es una sintaxis especial para campos de constructores. En su caso, usted podría tener

interface I { 
    getName():string; 
} 

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

Observe cómo la clase C no especifica el campo name. En realidad se declara usando azúcar sintáctico public name: string en el constructor.

Como señala Sohnee, se supone que la interfaz oculta todos los detalles de implementación. En mi ejemplo, he elegido la interfaz para requerir un método getter estilo java. Sin embargo, también puede hacer una propiedad y luego dejar que la clase decida cómo implementar la interfaz.

+1

Puede usar las palabras clave 'get' y' set' en TypeScript. – Fenton

+0

Gracias. He actualizado mi respuesta. – Valentin

+0

Una nota al margen sobre el soporte de ECMAScript 5 - 'Object.defineProperty' es compatible con IE8 +, FF4 +, Opera 12+, WebKit y Safari. También hay un EC5 Shim en https://github.com/kriskowal/es5-shim – Fenton

14

Como complemento de las otras respuestas, si su deseo es definir un get value en una interfaz, usted puede hacer esto:

interface Foo { 
    readonly value: number; 
} 

let foo: Foo = { value: 10 }; 

foo.value = 20; //error 

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

pero por lo que yo sepa , y como otros mencionaron, no hay manera de definir una propiedad de solo conjunto en la interfaz. Puede, sin embargo, mover la limitación a un error de tiempo de ejecución (útil durante el ciclo de desarrollo solamente):

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

práctica No se recomienda; pero una opción.

Cuestiones relacionadas