Menu

Class TypeScript: Field, Method, Getter, dan Implements

Class TypeScript adalah class JavaScript dengan field, method, dan constructor yang bertipe. Pelajari cara kerja deklarasi field dan strictPropertyInitialization, cara memberi tipe pada this, getter dan setter, member static, implements, dan bagaimana sebuah class sekaligus menjadi tipe.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Class TypeScript adalah class JavaScript dengan tipe: setiap field dideklarasikan beserta tipenya di badan class, dan method serta constructor mendapat parameter dan nilai kembalian yang bertipe.

Output hasil kompilasinya adalah class JavaScript biasa tanpa tipe, jadi semua yang ada di class JavaScript tetap berlaku. Tambahan dari TypeScript terjadi saat kompilasi: panggilan terakhir ditolak sebelum program dijalankan.

Mendeklarasikan Field

Sebuah field perlu dideklarasikan di badan class sebelum constructor bisa mengisinya. Mengisi this.owner tanpa mendeklarasikan owner menghasilkan error TS2339 (property tidak ada). Field dengan nilai awal mendapat tipe hasil inferensi dari nilainya, sama seperti variabel.

DeklarasiArti
name: string;Wajib diisi di constructor
count = 0;Diberi nilai awal, tipe disimpulkan sebagai number
label?: string;Opsional, tipenya string | undefined
readonly id: number;Diisi sekali, lalu hanya bisa dibaca
data!: string[];Definite assignment: percayalah, nanti diisi
static total = 0;Milik class, bukan milik instance

Dengan strict menyala, strictPropertyInitialization memeriksa bahwa setiap field yang tidak opsional mendapat nilai. Class ini lupa mengisi dua field:

Compiler melaporkan keduanya:

index.ts(3,5): error TS2564: Property 'name' has no initializer and is not definitely assigned in the constructor.
index.ts(4,5): error TS2564: Property 'age' has no initializer and is not definitely assigned in the constructor.

Pemeriksaan ini ada karena tanpanya new Profile().name.toUpperCase() akan lolos pemeriksaan tipe lalu crash karena undefined. Perbaiki setiap field dengan salah satu dari empat cara: beri nilai awal, isi di constructor, tandai sebagai opsional dengan ?, atau tulis name!: string kalau sebuah framework atau method init() mengisinya belakangan. Cara terakhir mematikan pemeriksaan untuk field itu, jadi pakai seperlunya.

Method dan this

Method diberi tipe seperti fungsi. Di dalam method, this bertipe instance. Method bisa mengembalikan this supaya bisa dirangkai (chaining), dan tipe kembaliannya otomatis mengikuti subclass.

class QueryBuilder {
    private parts: string[] = [];

    where(condition: string): this {
        this.parts.push(condition);
        return this;
    }

    build(): string {
        return this.parts.join(" AND ");
    }
}

const sql = new QueryBuilder().where("age > 18").where("active = 1").build();
console.log(sql); // age > 18 AND active = 1

Method kehilangan this-nya saat kamu mengambilnya dari objek, bug JavaScript yang klasik. TypeScript tidak menangkapnya secara default, tetapi akan menangkapnya kalau method itu mendeklarasikan parameter this. Parameter itu dihapus dari output dan hanya menjaga tempat pemanggilan:

Field arrow function berhasil karena setiap instance mendapat fungsinya sendiri yang menangkap this. Konsekuensinya, ada satu fungsi per instance, bukan satu method bersama di prototype.

Getter dan Setter

Accessor get dan set terlihat seperti property dari luar. Getter tanpa setter bersifat read only: mengisinya adalah error kompilasi (TS2540).

Compiler menolak penugasan itu, dan kalau pemeriksaannya dilewati, runtime juga melempar TypeError, karena file hasil kompilasi berjalan dalam strict mode (compiler menulis "use strict" di bagian atas). RangeError di setter adalah pemeriksaan runtime yang kamu tulis sendiri. Tipe number hanya menyatakan bahwa nilainya angka; tipe itu tidak tahu apa-apa soal rentang.

Member Static

Field dan method static adalah milik class itu sendiri. Kamu mengaksesnya lewat nama class, bukan lewat instance. Blok static { } dijalankan sekali saat class didefinisikan.

Member static tidak bisa memakai type parameter milik class: di class Box<T>, static empty: T menghasilkan error TS2302, karena hanya ada satu field static yang dipakai bersama oleh setiap Box<string>, Box<number>, dan seterusnya.

Mengimplementasikan Interface

implements meminta compiler memeriksa bahwa class itu punya semua yang diwajibkan sebuah interface. Member yang tidak ada menghasilkan error TS2420: Class 'X' incorrectly implements interface 'Y'.

Sebuah class bisa mengimplementasikan beberapa interface: class Doc implements Printable, Serializable. Ada dua hal yang tidak dilakukan implements. Ia tidak memberi tipe pada parameter method class untukmu: check(s) { ... } di dalam class yang mengimplementasikan check(s: string): boolean tetap menghasilkan error TS7006 (Parameter 's' implicitly has an 'any' type), jadi beri anotasi. Dan ia tidak meninggalkan jejak saat runtime, jadi obj instanceof Shape tidak mungkin dilakukan.

private radius di constructor adalah parameter property: field dideklarasikan dan diisi dalam satu langkah. Lihat constructor.

Class Juga Sebuah Tipe

Deklarasi class menciptakan dua hal dengan satu nama: sebuah nilai (fungsi constructor yang kamu panggil dengan new) dan sebuah tipe (bentuk instance-nya). Karena TypeScript membandingkan tipe berdasarkan strukturnya, objek apa pun dengan member public yang sama cocok dengan tipe itu, bahkan yang tidak dibuat oleh class tersebut.

Objek biasa itu lolos pemeriksaan tipe, tetapi bukan Point saat runtime: ({ x: 6, y: 8 }) instanceof Point bernilai false. Class dengan member private atau #private mencegah hal ini: hanya instance dari class itu (atau subclass-nya) yang bisa diberikan kepadanya.

Kesalahan Umum

  • Mendeklarasikan field tetapi tidak pernah mengisinya. TS2564 memberitahumu bahwa field itu akan bernilai undefined. Beri nilai awal, jangan dibungkam dengan !.
  • Mengirim method sebagai callback. button.onclick = obj.handle kehilangan this. Pakai field arrow function atau obj.handle.bind(obj).
  • Mengira implements menambahkan kode atau tipe. Ia hanya memeriksa. Tipe parameter tetap perlu anotasi.
  • Memakai instanceof dengan interface. Interface tidak ada saat runtime; periksa class atau pakai type guard.
  • Mengira tipe memvalidasi data. Field number menerima angka apa pun saat kompilasi, dan apa saja dari data tanpa tipe saat runtime.

Pertanyaan yang sering diajukan

Bagaimana cara membuat class di TypeScript?

Deklarasikan setiap field beserta tipenya di badan class, lalu tulis constructor dan method seperti di JavaScript: class User { name: string; constructor(name: string) { this.name = name; } greet(): string { return "Hi, " + this.name; } }. Buat instance dengan new User("Ada").

Apa arti "has no initializer and is not definitely assigned in the constructor"?

Itu error TS2564 dari strictPropertyInitialization (bagian dari strict). Field bertipe string akan bernilai awal undefined karena tidak ada yang mengisinya. Perbaiki dengan nilai awal (name = ""), penugasan di constructor, field opsional (name?: string), atau, kalau ada hal di luar constructor yang mengisinya, definite assignment assertion (name!: string).

Apa bedanya implements dan extends di TypeScript?

extends mewarisi kode dari class induk: field dan method-nya ada pada class anak saat runtime. implements hanya meminta compiler memeriksa bahwa class itu punya bentuk sebuah interface. Ia tidak menambahkan apa pun ke class dan hilang dari JavaScript hasil kompilasi.

Apakah class bisa dipakai sebagai tipe di TypeScript?

Bisa. Nama class sekaligus merupakan nilai (constructor-nya) dan tipe (bentuk instance-nya). let u: User menerima objek apa pun dengan member public yang sama, karena TypeScript membandingkan tipe secara struktural. typeof User adalah tipe dari constructor itu sendiri.

Apakah class TypeScript berbeda dengan class JavaScript saat runtime?

Tidak. TypeScript mengompilasi class menjadi class JavaScript biasa. Anotasi tipe, klausa implements, dan modifier seperti private dihapus; hanya fitur JavaScript seperti field #private, blok static, dan getter yang ada saat runtime.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai