Constructor di TypeScript adalah method constructor milik class dengan parameter yang bertipe. Constructor tidak punya anotasi tipe kembalian: ia selalu menghasilkan instance dari class itu.
Menulis constructor(): Product menghasilkan error TS1093 (Type annotation cannot appear on a constructor declaration). Selebihnya, cara kerja new adalah JavaScript biasa.
Parameter Property
Pola di atas (deklarasikan field, terima parameter, salin nilainya) begitu umum sampai TypeScript punya bentuk singkatnya. Taruh public, private, protected, atau readonly sebelum parameter constructor, dan parameter itu menjadi field:
Ini salah satu dari sedikit fitur TypeScript yang menghasilkan kode. Compiler menuliskan penugasannya untukmu:
class Product {
name;
price;
sku;
constructor(name, price, sku) {
this.name = name;
this.price = price;
this.sku = sku;
}
// ...
}
Karena bukan sekadar tipe yang dihapus, parameter property tidak bisa berjalan dengan type stripping bawaan Node (node file.ts gagal dengan ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX), dan opsi compiler erasableSyntaxOnly melaporkannya sebagai error TS1294. Proyek yang menjalankan file .ts secara langsung menuliskan field-nya secara manual.
Parameter Opsional dan Default
Parameter constructor mengikuti aturan yang sama dengan parameter fungsi: ? membuatnya opsional, nilai default membuatnya opsional sekaligus mengisinya, dan parameter wajib ditulis lebih dulu.
Parameter property juga bisa punya nilai default. Tipe color di dalam class adalah string | undefined, jadi kode yang memakainya harus memeriksa undefined lebih dulu.
Untuk constructor dengan banyak opsi, satu objek opsi lebih enak dibaca daripada daftar parameter posisional yang panjang: constructor(opts: { prefix: string; level?: "info" | "debug" }).
Urutan Inisialisasi Field
Nilai awal field dijalankan sebelum badan constructor, dan parameter property diisi di awal badan constructor. Jadi nilai awal field tidak bisa membaca parameter property. TypeScript menangkap hal ini:
index.ts(3,18): error TS2729: Property 'size' is used before its initialization.
index.ts(3,30): error TS2729: Property 'size' is used before its initialization.
Saat runtime, nilai awal itu akan melihat undefined dan menghasilkan NaN. Hitung nilainya di badan constructor sebagai gantinya:
class Grid {
cells: number;
constructor(public size: number) {
this.cells = size * size;
}
}
console.log(new Grid(3).cells); // 9
Overload Constructor
Sebuah class punya tepat satu implementasi constructor, tetapi kamu bisa mencantumkan beberapa overload signature di atasnya. Pemanggil hanya melihat overload-nya; signature implementasinya harus kompatibel dengan semuanya.
Overload jadi sulit dibaca kalau bentuknya lebih dari dua atau tiga. Method factory static dengan nama yang deskriptif (Color.fromHex("#ff8800"), Color.fromRgb(10, 20, 30)) sering kali lebih jelas dan tidak butuh penyempitan tipe di dalam satu badan fungsi.
Memanggil super di Subclass
Class turunan yang mendeklarasikan constructor-nya sendiri wajib memanggil super(...) dengan argumen untuk class induk, dan harus melakukannya sebelum menyentuh this. Lupa memanggilnya menghasilkan error TS2377 (Constructors for derived classes must contain a 'super' call), dan memakai this lebih dulu menghasilkan TS17009 ('super' must be called before accessing 'this' in the constructor of a derived class). Keduanya mencerminkan aturan runtime JavaScript.
class Animal {
constructor(public name: string) {}
}
class Dog extends Animal {
tricks: string[];
constructor(name: string, ...tricks: string[]) {
super(name); // must come first
this.tricks = tricks;
}
}
const rex = new Dog("Rex", "sit", "roll");
console.log(rex); // Dog { name: 'Rex', tricks: [ 'sit', 'roll' ] }
Subclass yang tidak menambahkan constructor akan mewarisi constructor induknya, dengan tipe parameter yang sama. Penjelasan lebih lanjut tentang subclass ada di inheritance.
Constructor Private dan Setup Async
Constructor private hanya bisa dipanggil dari dalam class. Di luar class, new menghasilkan error TS2673. Dengan cara ini kamu memaksa pemanggil lewat factory, untuk singleton atau untuk setup yang harus asynchronous (constructor tidak bisa async).
private di sini hanyalah aturan saat kompilasi. JavaScript yang dihasilkan punya constructor biasa, jadi kode JavaScript biasa tetap bisa memanggil new Connection(...).
Tipe Constructor
Untuk menerima class sebagai nilai, beri tipe parameter dengan construct signature: new (...args) => Instance. typeof MyClass juga bisa, tetapi itu mengikat parameter ke signature constructor dan member static milik satu class itu saja.
ConstructorParameters dan InstanceType mengekstrak tuple parameter dan tipe instance dari sebuah tipe constructor; keduanya dibahas bersama helper fungsi lainnya di ReturnType dan Parameters.
Pertanyaan yang sering diajukan
Apa itu parameter property di TypeScript?
Parameter constructor dengan modifier (public, private, protected, atau readonly) mendeklarasikan field dan mengisinya dalam satu langkah. constructor(private name: string) {} adalah singkatan dari mendeklarasikan private name: string dan menulis this.name = name. Compiler menghasilkan penugasan itu di output.
Apakah class TypeScript bisa punya beberapa constructor?
Tidak dengan beberapa implementasi. Sebuah class punya satu constructor, tetapi kamu bisa menulis beberapa overload signature di atasnya sehingga pemanggil melihat daftar parameter yang berbeda-beda. Method factory static seperti Color.fromHex() dan Color.fromRgb() sering kali lebih jelas daripada overload.
Apakah constructor bisa async di TypeScript?
Tidak. Constructor selalu mengembalikan instance baru, tidak pernah promise, dan async constructor() ditolak dengan error TS1089 ('async' modifier cannot appear on a constructor declaration). Pakai constructor private ditambah method static async create() yang mengerjakan proses asynchronous lalu memanggil new.
Bagaimana cara memberi tipe constructor class sebagai parameter?
Pakai construct signature: new (name: string) => User, atau typeof User untuk class itu secara persis. Factory generic bentuknya seperti function make<T>(ctor: new () => T): T { return new ctor(); }. ConstructorParameters<typeof User> memberikan daftar parameternya sebagai tuple.
Kenapa muncul "'super' must be called before accessing 'this'"?
Itu error TS17009. Di class yang extends class lain, constructor induk yang membuat objeknya, jadi this belum ada sampai super(...) dijalankan. Pindahkan pemanggilan super ke atas setiap baris yang menyentuh this.