2012-10-11 14 views
47

W tej chwili TypeScript nie zezwala na użycie metod get/set (accessors) w interfejsach. Na przykład:Czy można używać obiektów pobierających/ustawiających w definicji interfejsu?

interface I { 
     get name():string; 
} 

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

ponadto, maszynopis nie pozwala na wyrażenie funkcyjne stosowanie metod Array Klasa: ex .:

class C { 
    private _name:string; 

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

Czy istnieje inny sposób mogę użyć getter i setter na definicja interfejsu?

Odpowiedz

64

Można określić właściwość na interfejsie, ale nie można wymusić, czy pobierające i ustawiające są wykorzystywane w następujący sposób:

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

W tym przykładzie, interfejs nie zmusi klasę używać pobierające i ustawiające, mogłem użyć właściwości zamiast tego (przykład poniżej) - ale interfejs powinien ukryć te szczegóły implementacji, ponieważ jest to obietnica dla kodu wywołującego o tym, co może wywołać.

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

I wreszcie, => nie jest dozwolona dla metod klasy - można start a discussion on Codeplex jeśli uważasz, że jest palenie przypadek użycia dla niego. Oto przykład:

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

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

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

Możesz użyć '=>' do zdefiniowania takich metod klasy: 'name = (a: string) => this._name;' ale w wyjściowym JS będzie on zdefiniowany wewnątrz funkcji klasy zamiast rozszerzania jego prototypowego obiektu. – orad

3

Przede wszystkim, maszynopis obsługuje tylko get i set składnia gdy targetting ECMAScript 5. Aby to osiągnąć, trzeba zadzwonić kompilator z

tsc --target ES5 

Interfejsy nie obsługują pobierające i ustawiające. Aby otrzymać kod do kompilowania trzeba by zmienić go na

interface I { 
    getName():string; 
} 

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

Co maszynopis obsługuje to specjalna składnia polach konstruktorów. W Twoim przypadku można mieć

interface I { 
    getName():string; 
} 

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

zauważyć, jak klasa C nie określać dziedzinę name. Faktycznie jest on deklarowany za pomocą syntaktycznego cukru public name: string w konstruktorze.

Jak zauważa Sohnee, interfejs ma właściwie ukryć szczegóły implementacji. W moim przykładzie wybrałem interfejs wymagający metody pobierającej w stylu java. Możesz jednak także własność, a następnie niech klasa zdecyduje, jak zaimplementować interfejs.

+1

Możesz użyć słów kluczowych "get" i "set" w TypeScript. – Fenton

+0

Dzięki. Zaktualizowałem swoją odpowiedź. – Valentin

+0

Notatka boczna na temat obsługi ECMAScript 5 - "Object.defineProperty" jest obsługiwana w IE8 +, FF4 +, Opera 12+, WebKit i Safari. Istnieje również EC5 Shim na https://github.com/kriskowal/es5-shim – Fenton

14

Aby uzupełnić inne odpowiedzi, jeśli twoje pragnienie jest zdefiniowanie get value na interfejsie, można to zrobić:

interface Foo { 
    readonly value: number; 
} 

let foo: Foo = { value: 10 }; 

foo.value = 20; //error 

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

ale o ile jestem świadomy , a jak wspomnieliśmy inni, nie ma obecnie możliwości zdefiniowania właściwości "tylko zestaw" w interfejsie. Można jednak przenieść ograniczenie do błędu w czasie (przydatne tylko podczas cyklu rozwojowego):

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

nie zalecanych praktyk; ale opcja.

Powiązane problemy