classreadonlymodifierMahir3 mnt baca

readonly

Properti yang hanya bisa diisi sekali: readonly di class dan object.

Kenapa readonly Ada

Bug yang menyebalkan: id sebuah order berubah di tengah proses. Order ORD-1 tiba-tiba menjadi ORD-2 karena ada satu baris kode di sudut codebase yang assign ulang order.id. Tanpa readonly, compiler diam saja. Dengan readonly, baris itu langsung merah saat kamu menulisnya, bukan saat customer komplain.

readonly adalah cara termurah untuk menyatakan maksud: "properti ini diisi sekali saat object lahir, setelah itu jangan pernah diubah." Ini bukan soal keamanan dari hacker, tapi soal keamanan dari diri sendiri dan rekan tim enam bulan dari sekarang yang lupa aturan mainnya.

Kapan Dipakai di Project Nyata

  • ID entity: id order, user, produk. ID tidak pernah berubah sepanjang hidup object. Di ORM seperti TypeORM atau Prisma, pola ini standar.
  • Config yang di-inject sekali: apiUrl, timeout, apiKey di service class. Diisi di constructor dari environment, lalu terkunci.
  • Timestamp: dibuatPada: Date yang diisi new Date() saat construction.
  • Parameter properties: shorthand constructor(readonly id: string) sangat idiomatis untuk DTO dan entity, menghemat deklarasi properti manual.

Contoh 1: Entity Order yang ID-nya Tidak Bisa Diutak-atik

typescript
class Order {
  readonly tanggal: Date = new Date();

  constructor(
    readonly id: string,
    public status: string
  ) {}
}

const o = new Order("ORD-1", "baru");
o.status = "dikirim"; // OK, status memang boleh berubah
o.id = "ORD-2";
// Error: Cannot assign to 'id' because it is a read-only property. (TS2540)

TS2540 muncul tepat di baris yang mencoba mengubah. Perhatikan readonly boleh diisi di dua tempat: saat deklarasi (tanggal) atau di constructor (id). Setelah construction selesai, keduanya terkunci permanen.

Contoh 2: Jebakan readonly yang Shallow

Ini jebakan paling umum. readonly hanya melarang reassign propertinya, bukan mutasi isi object-nya:

typescript
class Kos {
  readonly penghuni: string[] = ["Budi"];
}

const kos = new Kos();
// kos.penghuni = []; // Error TS2540, reassign dilarang
kos.penghuni.push("Ani"); // LOLOS! isi array tetap bisa dimutasi
console.log(kos.penghuni); // ["Budi", "Ani"]

Kalau kamu butuh array yang benar-benar tidak bisa diubah, gabungkan dua readonly:

typescript
class KosAman {
  readonly penghuni: readonly string[] = ["Budi"];
}

const ka = new KosAman();
// ka.penghuni.push("Ani");
// Error: Property 'push' does not exist on type 'readonly string[]'. (TS2339)

Aturan praktisnya: readonly di properti mengunci referensinya, readonly di tipe array mengunci isinya. Untuk object bertingkat, pertimbangkan utility type Readonly<T> atau library immutable bila datanya kompleks.

Contoh 3: readonly di Interface Response API

typescript
interface ResponApi {
  readonly requestId: string;
  readonly waktu: number;
  data: unknown;
}

function proses(r: ResponApi): void {
  // r.requestId = "x"; // Error TS2540
  console.log(r.requestId, r.waktu);
}

Pola ini bagus untuk response API: metadata seperti requestId tidak boleh diubah oleh kode hilir, tapi data tetap bisa diolah bebas.

Catatan teknis: readonly vs const: const untuk variabel (variabelnya tidak bisa di-reassign), readonly untuk properti (propertinya tidak bisa di-reassign setelah inisialisasi). Keduanya compile-time only dan hilang total di JavaScript hasil kompilasi, jadi tidak ada biaya runtime sama sekali.

Tantangan

Entity abadi

Buat class Order dengan readonly id: string, readonly tanggal: Date (isi dengan new Date()), dan public status: string. Buktikan id tidak bisa diubah setelah construction, tapi status bisa.

typescript
class Order {
  readonly tanggal: Date = new Date();

  constructor(
    readonly id: string,
    public status: string
  ) {}
}

const o = new Order("ORD-1", "baru");
o.status = "dikirim"; // OK
// o.id = "ORD-2"; // Error!

Kuis Bab

Uji pemahamanmu: OOP & Modul

Jawab 5 soal berikut, lalu tekan "Periksa Jawaban".

1.Apa risiko memakai as (type assertion)?

2.Kapan memakai import type dibanding import biasa?

3.Apa fungsi implements pada class?

4.Apa beda private dan protected?

5.Apa arti readonly pada properti class?