Apakah mungkin untuk menggunakan getter / setter dalam definisi antarmuka?

93

Saat ini, TypeScripttidak mengizinkan penggunaan metode get / set (pengakses) di antarmuka. Sebagai contoh:

interface I {
      get name():string;
}

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

Selain itu, TypeScript tidak mengizinkan penggunaan Array Function Expression dalam metode kelas: misalnya:

class C {
    private _name:string;

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

Apakah ada cara lain saya dapat menggunakan getter dan setter pada definisi antarmuka?

Ivan Popov
sumber

Jawaban:

126

Anda dapat menentukan properti pada antarmuka, tetapi Anda tidak dapat menerapkan apakah getter dan setter digunakan, seperti ini:

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

Dalam contoh ini, antarmuka tidak memaksa kelas untuk menggunakan getter dan setter, saya bisa saja menggunakan properti sebagai gantinya (contoh di bawah) - tetapi antarmuka seharusnya menyembunyikan detail implementasi ini karena itu adalah janji untuk kode panggilan tentang apa yang bisa disebut.

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

Dan terakhir, =>tidak diperbolehkan untuk metode kelas - Anda dapat memulai diskusi tentang Codeplex jika menurut Anda ada kasus penggunaan burning untuk itu. Berikut ini contohnya:

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

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

    // No
    get name() => 'Steve';
}
Fenton
sumber
1
Anda dapat menggunakan =>untuk mendefinisikan metode kelas seperti ini: name = (a: string) => this._name;tetapi dalam keluaran JS, ia akan didefinisikan di dalam fungsi kelas daripada memperluas objek prototipe-nya.
orad
ini tampaknya tidak bekerja dengan properti get statis: /
CervEd
46

Untuk melengkapi jawaban lainnya, jika keinginan Anda adalah untuk mendefinisikan get valuesebuah antarmuka, Anda dapat menggunakan readonly:

interface Foo {
  readonly value: number;
}

let foo: Foo = { value: 10 };

foo.value = 20; //error

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

tetapi sejauh yang saya ketahui, dan seperti yang disebutkan orang lain, saat ini tidak ada cara untuk mendefinisikan properti set-only di antarmuka. Namun, Anda dapat memindahkan batasan ke error run-time (berguna hanya selama siklus pengembangan):

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

Latihan yang tidak direkomendasikan ; tapi sebuah pilihan.

Meirion Hughes
sumber
2

Pertama-tama, Typecript hanya mendukung getdan setsintaks saat menargetkan Ecmascript 5. Untuk mencapai ini, Anda harus memanggil kompilator dengan

tsc --target ES5

Antarmuka tidak mendukung getter dan setter. Untuk mendapatkan kode Anda untuk dikompilasi, Anda harus mengubahnya menjadi

interface I { 
    getName():string;
}

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

Skrip jenis apa yang mendukung adalah sintaks khusus untuk bidang di konstruktor. Dalam kasus Anda, Anda dapat melakukannya

interface I {
    getName():string;
}

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

Perhatikan bagaimana kelas Ctidak menentukan bidang name. Ini sebenarnya dideklarasikan menggunakan gula sintaksis public name: stringdi konstruktor.

Seperti yang ditunjukkan Sohnee, antarmuka sebenarnya seharusnya menyembunyikan detail implementasi apa pun. Dalam contoh saya, saya telah memilih antarmuka yang memerlukan metode pengambil gaya java. Namun, Anda juga dapat memiliki properti dan kemudian membiarkan kelas memutuskan cara mengimplementasikan antarmuka.

Valentin
sumber
1
Anda dapat menggunakan getdan setkata kunci di TypeScript.
Fenton
Catatan tambahan tentang dukungan ECMAScript 5 - Object.definePropertydidukung di IE8 +, FF4 +, Opera 12+, WebKit dan Safari. Ada juga Shim EC5 di github.com/kriskowal/es5-shim
Fenton
-1

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

Lihat contoh di TypeScript Playground .

Mendongkrak
sumber