Topik ini membahas anatomi kelas TypeScript, mulai dari deklarasi field, modifier readonly, hingga parameter properties yang memangkas tulisan berulang pada konstruktor. Ketiganya mengatur bagaimana data disimpan pada objek, kapan nilainya boleh berubah, dan seberapa ringkas kodenya. Setelah topik ini dipelajari, kelas yang datanya terdefinisi dengan baik dapat ditulis tanpa deklarasi berlebihan dan tanpa peringatan dari pemeriksa tipe.
Field dan anotasi tipenya#
Field adalah variabel yang melekat pada sebuah objek dan dideklarasikan langsung di dalam tubuh kelas. TypeScript melengkapi field dengan anotasi tipe, sehingga tipe nilai yang ditampung setiap field dapat dinyatakan secara eksplisit. Nilai awalnya dapat ditulis langsung pada deklarasi apabila nilainya sama untuk semua objek. Alternatifnya, field diisi melalui konstruktor, yaitu metode khusus yang dijalankan ketika instance dibuat dengan kata kunci new. Berkas arsip.ts berikut memuat ketiga bentuk tersebut pada satu kelas.
class BarangArsip {
kode: string;
nama: string;
jumlah: number = 0;
constructor(kode: string, nama: string) {
this.kode = kode;
this.nama = nama;
}
terima(jumlahMasuk: number): void {
this.jumlah = this.jumlah + jumlahMasuk;
}
}
const barang = new BarangArsip("INV-014", "kertas HVS A4");
console.log(barang.kode);
console.log(barang.nama);
console.log(barang.jumlah);
barang.terima(50);
console.log(barang.jumlah);INV-014
kertas HVS A4
0
50Field jumlah bernilai awal 0 dan bertambah setiap metode terima() dipanggil, sedangkan kode dan nama diisi melalui argumen konstruktor. Pemisahan ini membuat satu kelas dapat menghasilkan banyak objek dengan data yang berbeda. Urutan inisialisasinya juga ditentukan secara konsisten, yaitu field dengan nilai awal diisi lebih dahulu, baru tubuh konstruktor dijalankan, sehingga penugasan pada konstruktor selalu menjadi nilai akhir field. Pemahaman urutan ini mencegah kebingungan ketika nilai awal dan penugasan konstruktor mengisi field yang sama.
Dalam strict mode, yaitu kumpulan opsi pemeriksaan paling ketat milik TypeScript, field yang tidak diinisialisasi di salah satu tempat itu ditolak dengan error TS2564 yang menyatakan field belum memiliki nilai pasti. Perlindungan ini menutup kelalaian berupa field yang terbaca sebagai undefined saat dipakai. Kelas contoh di atas lolos pemeriksaan tersebut karena setiap fieldnya terisi di salah satu dari dua tempat itu.
Modifier readonly#
Modifier readonly dipasang pada field untuk menjamin nilainya hanya diisi satu kali, yaitu pada deklarasi atau di dalam konstruktor. Setelah objek selesai dibuat, penulisan ulang nilai field tersebut ditolak pemeriksa tipe. Jaminan ini berlaku pada saat kompilasi saja karena field readonly tetap merupakan properti biasa pada program yang telah dikompilasi. Berkas arsip-readonly-salah.ts berikut sengaja menuliskan ulang nilai field readonly, sehingga berkas ini tidak dijalankan dan hanya diperiksa tipenya.
// tidak-dijalankan
class DokumenArsip {
readonly kodeDokumen: string;
constructor(kodeDokumen: string) {
this.kodeDokumen = kodeDokumen;
}
gantiKode(kodeBaru: string): void {
this.kodeDokumen = kodeBaru;
}
}# periksa tipe tanpa menghasilkan berkas keluaran
tsc --noEmit --pretty false arsip-readonly-salah.tsarsip-readonly-salah.ts(10,10): error TS2540: Cannot assign to 'kodeDokumen' because it is a read-only property.Pesan error TS2540 menyatakan properti hanya dapat dibaca sehingga penugasannya ditolak. Perilaku ini perlu dibedakan dari Object.freeze() pada JavaScript yang benar-benar membekukan objek saat program berjalan. Modifier readonly tidak mengubah perilaku program sedikit pun dan hanya menutup jalur perubahan sebelum program dijalankan. Karena itu keduanya dapat dipadukan apabila ketahanan pada saat runtime juga dibutuhkan.
Modifier readonly juga dapat menyertai field pada parameter properties, sehingga penulisan ringkas dan jaminan ketidakberubahan diperoleh sekaligus. Apabila objek memiliki banyak field yang seharusnya tidak berubah, memberi readonly pada semuanya membuat pelanggaran terdeteksi lebih dini. Biayanya hanya berupa tulisan tambahan pada deklarasi.
Parameter properties#
Parameter properties adalah fitur TypeScript yang mengubah parameter konstruktor bermodifier menjadi field secara otomatis. Menuliskan public kode: string pada daftar parameter sama saja dengan mendeklarasikan field kode, lalu menugaskan this.kode = kode di dalam konstruktor. Deklarasi dan penugasan cukup ditulis satu kali pada parameter, sehingga kelas dengan banyak field menjadi jauh lebih ringkas. Karena parameter properties tidak punya padanan JavaScript, berkas inventaris.ts dijalankan dengan flag --experimental-transform-types milik Node.js, yaitu mode transformasi penuh yang menangani fitur di luar penghapusan tipe.
// tidak-dijalankan
class ItemInventaris {
constructor(
public kode: string,
private lokasiRak: string,
readonly jumlah: number,
) {}
alamat(): string {
return `${this.kode} disimpan di ${this.lokasiRak}`;
}
}
const item = new ItemInventaris("INV-021", "rak B2", 12);
console.log(item.kode);
console.log(item.alamat());
console.log(item.jumlah);# menjalankan kelas dengan parameter properties melalui mode transformasi
node --experimental-transform-types --no-warnings inventaris.tsINV-021
INV-021 disimpan di rak B2
12Keluaran menunjukkan ketiga field dapat diakses sesuai modifier masing-masing. Field kode bersifat public sehingga terbaca dari luar kelas, sedangkan lokasiRak bersifat private dan hanya digunakan oleh metode alamat(). Pada hasil kompilasi, parameter properties menjadi deklarasi field dan penugasan eksplisit, sehingga fitur ini hanya milik TypeScript dan tidak dapat ditulis pada berkas JavaScript murni.
Parameter properties boleh berdampingan dengan parameter biasa pada konstruktor yang sama. Parameter yang tidak membawa modifier hanya menjadi argumen biasa tanpa menghasilkan field, sehingga nilai tambahan tanpa penyimpanan tetap dapat diterima. Apabila field bermodifier juga dinyatakan readonly, nilainya hanya dapat diisi oleh konstruktor dan bebas dibaca setelahnya.
Pemilihan bentuk penulisan field dapat dirangkum sebagai berikut.
| Bentuk penulisan | Kondisi yang tepat |
|---|---|
| Inisialisasi langsung pada deklarasi | Nilai sama untuk semua objek, misalnya penghitung yang dimulai dari nol. |
| Deklarasi field lalu penugasan di konstruktor | Nilai perlu dihitung atau divalidasi sebelum disimpan. |
| Parameter properties | Nilai langsung berasal dari argumen konstruktor tanpa pengolahan tambahan. |
Kesalahan umum#
Tiga kesalahan berikut berhubungan langsung dengan cara field dideklarasikan dan dilindungi. Ketiganya terdeteksi pada saat kompilasi atau terlihat jelas pada hasil kompilasinya. Meninjau ketiganya membantu memilih bentuk deklarasi yang tepat sejak awal.
- Field tanpa inisialisasi ditolak dalam strict mode dengan error TS2564. Perbaikannya melalui tiga jalur, yaitu inisialisasi langsung, penugasan di konstruktor, atau parameter properties. Apabila nilai benar-benar diisi oleh metode lain, nyatakan tipenya mencakup
undefineddan beri nilai awalundefined. - Mengira
readonlymembekukan seluruh objek. Modifier hanya melindungi satu field, sedangkan field lain tetap dapat ditulis dan metode tetap dapat mengubah keadaan objek. GunakanObject.freeze()bila ketahanan pada saat runtime diperlukan. - Menyalin sintaks parameter properties ke berkas JavaScript murni. Fitur ini tidak ada pada JavaScript sehingga hasilnya error sintaks. Jalankan kode melalui alur kompilasi TypeScript atau tulis deklarasi field beserta penugasannya secara eksplisit.
Ringkasan#
- Field dideklarasikan dengan anotasi tipe dan diisi pada deklarasi atau konstruktor, sedangkan strict mode menuntut kepastian inisialisasi melalui error TS2564.
- Modifier
readonlymenolak penulisan ulang nilai field pada saat kompilasi tanpa mengubah perilaku program berjalan. - Parameter properties mengubah parameter konstruktor bermodifier menjadi field sehingga deklarasi dan penugasan tidak ditulis dua kali.
- Seluruh anotasi tipe dan sintaks khusus TypeScript hilang pada hasil kompilasi, sehingga tidak menambah biaya apa pun saat program berjalan.
Referensi#
- Classes — TypeScript Handbook — Dokumentasi modifier readonly beserta parameter properties pada kelas TypeScript.
- strictPropertyInitialization — TypeScript tsconfig Reference — Aturan strict mode yang menuntut inisialisasi setiap field kelas.