Arayüz tanımında alıcı / ayarlayıcı kullanmak mümkün müdür?


93

Şu anda TypeScriptarayüzlerde get / set yöntemlerinin (erişimciler) kullanılmasına izin vermiyor. Örneğin:

interface I {
      get name():string;
}

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

ayrıca TypeScript, sınıf yöntemlerinde Array Function Expression kullanımına izin vermez: örn .:

class C {
    private _name:string;

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

Bir alıcı ve ayarlayıcıyı bir arayüz tanımında kullanmanın başka bir yolu var mı?

Yanıtlar:


126

Özelliği arayüzde belirtebilirsiniz, ancak aşağıdaki gibi alıcıların ve ayarlayıcıların kullanılıp kullanılmayacağını belirleyemezsiniz:

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

Bu örnekte, arabirim sınıfı alıcıları ve ayarlayıcıları kullanmaya zorlamaz, bunun yerine bir özellik kullanabilirdim (aşağıdaki örnek) - ancak arabirimin bu uygulama ayrıntılarını yine de çağıran kod için bir vaat olduğu için gizlemesi gerekiyor ne arayabileceği hakkında.

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

Ve son olarak, =>sınıf yöntemlerine izin verilmez - bunun için yanan bir kullanım durumu olduğunu düşünüyorsanız , Codeplex hakkında bir tartışma başlatabilirsiniz . İşte bir örnek:

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

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

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

1
Bunun =>gibi sınıf yöntemlerini tanımlamak için kullanabilirsiniz : name = (a: string) => this._name;ancak çıktı JS'de prototip nesnesini genişletmek yerine sınıf işlevi içinde tanımlanacaktır.
orad

bu statik get özellikleriyle çalışmıyor gibi görünüyor: /
CervEd

46

Diğer cevapları tamamlamak için, eğer arzunuz get valuebir arayüz üzerinde bir tanımlama yapmaksa, şunu kullanabilirsiniz readonly:

interface Foo {
  readonly value: number;
}

let foo: Foo = { value: 10 };

foo.value = 20; //error

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

ancak bildiğim kadarıyla ve diğerlerinin de bahsettiği gibi, şu anda arayüzde bir salt-set özelliği tanımlamanın bir yolu yok. Bununla birlikte, sınırlamayı bir çalışma zamanı hatasına taşıyabilirsiniz (yalnızca geliştirme döngüsü sırasında faydalıdır):

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

Tavsiye edilmeyen uygulama ; ama bir seçenek.


2

Her şeyden önce, Typescript sadece Ecmascript 5'i hedeflerken destekler getve setsözdizimini destekler . Bunu başarmak için, derleyiciyi şu şekilde çağırmalısınız:

tsc --target ES5

Arayüzler alıcıları ve ayarlayıcıları desteklemez. Kodunuzun derlenmesini sağlamak için kodunuzu şu şekilde değiştirmeniz gerekir:

interface I { 
    getName():string;
}

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

Hangi tür yazısının desteklediği, kuruculardaki alanlar için özel bir sözdizimidir. Senin durumunda alabilirdin

interface I {
    getName():string;
}

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

Sınıfın Calanı nasıl belirtmediğine dikkat edin name. Aslında public name: stringyapıcıda sözdizimsel şeker kullanılarak beyan edilir .

Sohnee'nin de belirttiği gibi, arayüzün aslında herhangi bir uygulama detayını gizlemesi gerekiyor. Örneğimde, arayüzü java tarzı bir alıcı yöntemi gerektirecek şekilde seçtim. Ancak, bir özelliği de uygulayabilir ve ardından arabirimin nasıl uygulanacağına sınıfın karar vermesine izin verebilirsiniz.


1
TypeScript'te getve setanahtar sözcüklerini kullanabilirsiniz .
Fenton

ECMAScript 5 desteğiyle ilgili bir yan not - Object.definePropertyIE8 +, FF4 +, Opera 12+, WebKit ve Safari'de desteklenmektedir. Ayrıca github.com/kriskowal/es5-shim
Fenton

-1

TypeScript 3.4'ü kullanma:

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'daki örneğe bakın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.