Classes di TypeScript — TypeScript

TypeScript menambahkan fitur penting di atas class JavaScript: access modifiers dan abstract classes. Access Modifiers: class User { public nama: string //…

Di materi JavaScript kamu sudah bikin class: cetakan object, dengan constructor yang menyimpan data lewat this dan method yang membacanya. TypeScript menambahkan dua hal: tipe untuk tiap property, dan penanda akses (access modifier) yang menentukan dari mana sebuah property boleh dipakai. Bayangin kantor: ruang tamu terbuka buat siapa saja, pintu arsip ditempeli tulisan "Khusus karyawan", dan brankas dikunci beneran. Tulisan di pintu cuma ampuh selama ada satpam yang menegur, dan satpamnya adalah TypeScript waktu memeriksa kodemu.

🧪 Tebakan cepat: suara di class Hewan ditandai private, lalu di luar class kamu menulis console.log(kucing.suara). TypeScript memberi error. Kalau JavaScript hasil kompilasinya tetap dijalankan, apa yang tercetak: error, undefined, atau Meow? Tebak dulu, jawabannya ada di bagian "private cuma ada waktu dicek".

Property bertipe dan penanda akses

class Hewan {
  public nama: string
  private suara: string

  constructor(nama: string, suara: string) {
    this.nama = nama
    this.suara = suara
  }

  bersuara(): string {
    return this.nama + " bersuara: " + this.suara
  }
}

Siapa boleh menyentuh apa

Sekarang ada subclass Kucing, lalu kode di luar class yang membaca dan mengganti suara:

class Kucing extends Hewan {
  pamer(): string {
    return "Suaraku " + this.suara
  }
}

const kucing = new Kucing("Kucing", "Meow")
console.log(kucing.bersuara())
console.log(kucing.pamer())
console.log(kucing.suara)
kucing.suara = "Guk"
console.log(kucing.bersuara())

Ganti penanda di depan suara, dan TypeScript menilai tiap baris yang menyentuhnya:

Baris yang menyentuh suara public private protected readonly
di dalam Hewan, method bersuara boleh boleh boleh boleh
di subclass Kucing, method pamer boleh ts(2341) boleh boleh
di luar, baca kucing.suara boleh ts(2341) ts(2445) boleh
di luar, ganti kucing.suara = "Guk" boleh ts(2341) ts(2445) ts(2540)

Parameter properties: deklarasi dan isi sekaligus

Menulis suara tiga kali (deklarasi, parameter, this.suara = suara) itu capek. Jalan pintasnya: taruh penanda akses langsung di parameter constructor.

class Hewan {
  constructor(public nama: string, private suara: string) {}

  bersuara(): string {
    return this.nama + " bersuara: " + this.suara
  }
}

Sejak TypeScript 5.8 ada opsi erasableSyntaxOnly, untuk proyek yang menjalankan .ts cuma dengan menghapus tipenya (misalnya Node.js yang menjalankan file .ts langsung). Parameter property butuh kode tambahan di JavaScript (this.nama = nama), jadi kalau opsi itu nyala, dia ditolak: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. ts(1294). Di proyek seperti itu, pakai versi panjang.

private cuma ada waktu dicek

Tipe dan penanda akses cuma dipakai waktu TypeScript memeriksa kode. Waktu tsc mengubahnya jadi JavaScript, semuanya dihapus. Versi panjang maupun parameter property jadi JS yang sama:

class Hewan {
    nama;
    suara;
    constructor(nama, suara) {
        this.nama = nama;
        this.suara = suara;
    }
    // bersuara() tetap ada, tanpa ": string"
}

Kata private hilang, suara jadi property biasa. Jadi program Kucing tadi, kalau JS-nya tetap dijalankan walau ada error, mencetak Kucing bersuara: Meow, Suaraku Meow, Meow, lalu Kucing bersuara: Guk. kucing.suara mencetak Meow, dan gantinya ke Guk juga berhasil. Itu jawaban tebakannya. private itu tulisan "Khusus karyawan": TypeScript menegur di editor, tapi JavaScript-nya gak mengunci apa pun.

Butuh kunci beneran? Pakai private field bawaan JavaScript, yang diawali #:

class Hewan {
  #suara: string
  constructor(public nama: string, suara: string) {
    this.#suara = suara
  }
}

implements dan abstract class

implements adalah janji bahwa class memenuhi bentuk sebuah interface (dari materi Interface). Kalau class Robot implements BisaBersuara lupa menulis method bersuara() yang diminta interface-nya, TypeScript menolak: Class 'Robot' incorrectly implements interface 'BisaBersuara'. ts(2420).

abstract class adalah class yang cuma boleh jadi induk. Dia boleh punya method abstract: method tanpa isi yang wajib ditulis oleh tiap subclass.

abstract class Hewan {
  constructor(public nama: string) {}
  abstract bersuara(): string
}

class Kucing extends Hewan {
  bersuara(): string { return "Meow" }
}

new Kucing("Kucing").bersuara() // "Meow"
new Hewan("Siapa") // error ts(2511)

⚠️ Jebakan yang sering ketemu

TL;DR: Di class TypeScript, property dideklarasikan dengan tipenya. public boleh dari mana saja (bawaan), private cuma di dalam class itu, protected di class itu dan subclass-nya, readonly boleh dibaca tapi cuma diisi di deklarasi atau constructor. Parameter property, constructor(public nama: string, private suara: string) {}, mendeklarasikan dan mengisi sekaligus, asal ada penandanya (dan ditolak kalau erasableSyntaxOnly nyala). Semua penanda itu cuma dicek TypeScript dan hilang di JavaScript; kunci yang tetap ada waktu program jalan adalah #field. implements menjanjikan bentuk interface, abstract class gak bisa di-new dan memaksa subclass menulis method abstract-nya.

Yang akan kamu pelajari