TypeScript'te constructor, sınıfın tipli parametrelere sahip constructor metodudur. Dönüş tipi notasyonu yoktur: her zaman sınıfın bir örneğini üretir.
constructor(): Product yazmak TS1093 hatasıdır (Type annotation cannot appear on a constructor declaration). new ifadesinin nasıl çalıştığına dair geri kalan her şey sıradan JavaScript'tir.
Parametre Özellikleri
Yukarıdaki kalıp (bir alan bildir, bir parametre al, onu kopyala) o kadar yaygındır ki TypeScript'in bunun için bir kısaltması vardır. Bir constructor parametresinin önüne public, private, protected veya readonly koyarsanız parametre bir alana dönüşür:
Bu, kod üreten az sayıdaki TypeScript özelliğinden biridir. Atamaları derleyici sizin yerinize yazar:
class Product {
name;
price;
sku;
constructor(name, price, sku) {
this.name = name;
this.price = price;
this.sku = sku;
}
// ...
}
Yalnızca silinen tiplerden ibaret olmadığı için parametre özellikleri Node'un yerleşik tip ayıklamasıyla (type stripping) çalışmaz (node file.ts, ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX ile başarısız olur) ve erasableSyntaxOnly derleyici seçeneği onları TS1294 hatası olarak bildirir. .ts dosyalarını doğrudan çalıştıran projeler alanları elle yazar.
Opsiyonel ve Varsayılan Parametreler
Constructor parametreleri fonksiyon parametreleriyle aynı kurallara uyar: ? bir parametreyi opsiyonel yapar, varsayılan bir değer onu hem opsiyonel yapar hem de doldurur, zorunlu parametreler ise önce gelir.
Parametre özelliklerinin de varsayılan değerleri olabilir. Sınıfın içinde color tipi string | undefined olduğundan, onu kullanan kodun önce undefined kontrolü yapması gerekir.
Çok sayıda seçeneği olan constructor'larda, uzun bir konumsal liste yerine tek bir seçenek nesnesi daha kolay okunur: constructor(opts: { prefix: string; level?: "info" | "debug" }).
Alanların Başlatılma Sırası
Alan başlatıcıları constructor gövdesinden önce çalışır, parametre özellikleri ise constructor gövdesinin başında atanır. Bu yüzden bir alan başlatıcısı bir parametre özelliğini okuyamaz. TypeScript bunu yakalar:
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.
Çalışma zamanında başlatıcı undefined görür ve NaN üretirdi. Bunun yerine değeri constructor gövdesinde hesaplayın:
class Grid {
cells: number;
constructor(public size: number) {
this.cells = size * size;
}
}
console.log(new Grid(3).cells); // 9
Constructor Overload'ları
Bir sınıfın tam olarak bir constructor implementasyonu vardır, ancak üstünde birkaç overload imzası listeleyebilirsiniz. Çağıranlar yalnızca overload'ları görür; implementasyon imzasının hepsiyle uyumlu olması gerekir.
Overload'lar iki üç biçimden sonra zor okunur hale gelir. Açıklayıcı adlara sahip statik factory metotları (Color.fromHex("#ff8800"), Color.fromRgb(10, 20, 30)) çoğu zaman daha anlaşılırdır ve tek bir gövde içinde tip daraltma gerektirmez.
Alt Sınıfta super Çağırmak
Kendi constructor'ını bildiren türetilmiş bir sınıf, ebeveynin argümanlarıyla super(...) çağırmalı ve bunu this'e dokunmadan önce yapmalıdır. Çağrıyı unutmak TS2377 hatasıdır (Constructors for derived classes must contain a 'super' call), önce this kullanmak ise TS17009 hatasıdır ('super' must be called before accessing 'this' in the constructor of a derived class). İkisi de JavaScript'in çalışma zamanı kurallarının karşılığıdır.
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' ] }
Constructor eklemeyen bir alt sınıf, ebeveyninkini aynı parametre tipleriyle miras alır. Alt sınıflar hakkında daha fazlası için kalıtım sayfasına bakın.
Private Constructor'lar ve Asenkron Kurulum
private bir constructor yalnızca sınıfın içinden çağrılabilir. Dışarıda new kullanmak TS2673 hatasıdır. Çağıranları bir factory'den geçmeye böyle zorlarsınız: bir singleton için ya da asenkron olması gereken bir kurulum için (constructor'lar async olamaz).
Buradaki private yalnızca derleme zamanı kuralıdır. Üretilen JavaScript'te sıradan bir constructor vardır, bu yüzden düz JavaScript kodu yine de new Connection(...) çağırabilir.
Constructor Tipleri
Bir sınıfı değer olarak kabul etmek için parametreyi bir construct imzasıyla tipleyin: new (...args) => Instance. typeof MyClass da çalışır, ancak parametreyi o tek sınıfın constructor imzasına ve statik üyelerine bağlar.
ConstructorParameters ve InstanceType, bir constructor tipinden parametre tuple'ını ve örnek tipini çıkarır; diğer fonksiyon yardımcılarıyla birlikte ReturnType ve Parameters sayfasında anlatılır.
Sıkça Sorulan Sorular
TypeScript'te parametre özellikleri (parameter properties) nedir?
Bir belirleyiciye (public, private, protected veya readonly) sahip bir constructor parametresi, bir alanı tek adımda bildirir ve atar. constructor(private name: string) {}, private name: string bildirip this.name = name yazmanın kısaltmasıdır. Derleyici bu atamayı çıktıda üretir.
Bir TypeScript sınıfının birden fazla constructor'ı olabilir mi?
Birden fazla implementasyonu olamaz. Bir sınıfın tek bir constructor'ı vardır, ancak çağıranların farklı parametre listeleri görmesi için üstüne birkaç overload imzası yazabilirsiniz. Color.fromHex() ve Color.fromRgb() gibi statik factory metotları çoğu zaman overload'lardan daha anlaşılırdır.
TypeScript'te bir constructor async olabilir mi?
Hayır. Bir constructor her zaman yeni örneği döndürür, asla bir promise döndürmez; async constructor() ise TS1089 hatasıyla ('async' modifier cannot appear on a constructor declaration) reddedilir. Asenkron işi yapıp ardından new çağıran statik bir async create() metodu ile birlikte private bir constructor kullanın.
Bir sınıf constructor'ını parametre olarak nasıl tiplerim?
Bir construct imzası kullanın: new (name: string) => User, ya da tam olarak o sınıf için typeof User. Generic bir factory şöyle görünür: function make<T>(ctor: new () => T): T { return new ctor(); }. ConstructorParameters<typeof User> parametre listesini bir tuple olarak verir.
Neden "'super' must be called before accessing 'this'" hatası alıyorum?
Bu TS17009 hatasıdır. Başka bir sınıfı extends eden bir sınıfta nesneyi ebeveyn constructor oluşturur, bu yüzden super(...) çalışana kadar this yoktur. super çağrısını this'e dokunan her satırın üstüne taşıyın.