Menu

TypeScript Class: Alanlar, Metotlar, Getter'lar ve Implements

TypeScript sınıfları, tipli alanlara, metotlara ve constructor'lara sahip JavaScript sınıflarıdır. Alan bildirimlerinin ve strictPropertyInitialization'ın nasıl çalıştığını, this'e nasıl tip verileceğini, getter ve setter'ları, statik üyeleri, implements'i ve bir sınıfın nasıl aynı zamanda bir tip olduğunu öğrenin.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

Bir TypeScript sınıfı, tipleri olan bir JavaScript sınıfıdır: her alan sınıf gövdesinde tipiyle bildirilir, metotlar ve constructor da tipli parametreler ve dönüş değerleri alır.

Derlenmiş çıktı, tipleri kaldırılmış sıradan bir JavaScript sınıfıdır; bu yüzden JavaScript sınıfları sayfasındaki her şey hâlâ geçerlidir. TypeScript'in eklediği şeyler derleme zamanında olur: son çağrı program çalışmadan reddedilir.

Alan Bildirmek

Constructor'ın bir alana atama yapabilmesi için o alanın sınıf gövdesinde bildirilmesi gerekir. owner bildirilmeden this.owner ataması yapmak TS2339 hatasıdır (özellik yok). Başlangıç değeri olan bir alanın tipi, bir değişkende olduğu gibi değerden çıkarılır.

BildirimAnlamı
name: string;Constructor içinde atanmalıdır
count = 0;Başlatılmış, tipi number olarak çıkarılır
label?: string;Opsiyonel, tipi string | undefined
readonly id: number;Bir kez atanır, sonra yalnızca okunur
data!: string[];Kesin atama: bana güven, ayarlanacak
static total = 0;Örneklere değil, sınıfa aittir

strict açıkken strictPropertyInitialization, opsiyonel olmayan her alanın bir değer aldığını kontrol eder. Bu sınıf ikisini unutuyor:

Derleyici ikisini de bildirir:

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.

Kontrol vardır, çünkü o olmasaydı new Profile().name.toUpperCase() tip kontrolünden geçer ve sonra undefined ile çökerdi. Her alanı dört yoldan biriyle düzeltin: bir başlangıç değeri verin, constructor içinde atayın, ? ile opsiyonel yapın ya da bir framework veya bir init() metodu onu sonradan ayarlıyorsa name!: string yazın. Sonuncusu o alan için kontrolü kapatır, bu yüzden idareli kullanın.

Metotlar ve this

Metotlar fonksiyonlar gibi tiplenir. Bir metodun içinde this, örneğin tipine sahiptir. Bir metot zincirlemeye izin vermek için this döndürebilir ve dönüş tipi alt sınıfları otomatik olarak izler.

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

Bir metodu nesneden ayırdığınızda this değerini kaybeder; klasik bir JavaScript hatasıdır. TypeScript bunu varsayılan olarak yakalamaz, ama metot bir this parametresi bildiriyorsa yakalar. Bu parametre çıktıdan silinir ve yalnızca çağrı yerini korur:

Arrow alanı çalışır, çünkü her örnek this değerini kapsayan kendi fonksiyonunu alır. Bedeli, prototipte paylaşılan tek bir metot yerine örnek başına bir fonksiyondur.

Getter'lar ve Setter'lar

get ve set erişimcileri dışarıdan özellik gibi görünür. Setter'ı olmayan bir getter salt okunurdur: ona atama yapmak bir derleme hatasıdır (TS2540).

Derleyici atamayı reddeder ve kontrol atlatılsa bile çalışma zamanı da bir TypeError fırlatır, çünkü derlenmiş dosya strict modda çalışır (derleyici en üste "use strict" yazar). Setter'daki RangeError sizin kendiniz yazdığınız bir çalışma zamanı kontrolüdür. number tipi yalnızca değerin bir sayı olduğunu söyler; aralıklar hakkında hiçbir şey bilmez.

Statik Üyeler

static alanlar ve metotlar sınıfın kendisine aittir. Onlara bir örnek üzerinden değil, sınıf adı üzerinden erişirsiniz. Bir static { } bloğu sınıf tanımlandığında bir kez çalışır.

Statik üyeler sınıfın tip parametrelerini kullanamaz: class Box<T> içinde bir static empty: T TS2302 hatasıdır, çünkü her Box<string>, Box<number> ve diğerleri tarafından paylaşılan tek bir statik alan vardır.

Bir Interface Implement Etmek

implements, derleyiciden sınıfın bir interface'in gerektirdiği her şeye sahip olduğunu kontrol etmesini ister. Eksik bir üye TS2420 hatasıdır: Class 'X' incorrectly implements interface 'Y'.

Bir sınıf birkaç interface implement edebilir: class Doc implements Printable, Serializable. implements iki şeyi yapmaz. Sınıfın metot parametrelerini sizin için tiplemez: check(s: string): boolean implement eden bir sınıfın içindeki check(s) { ... } yine TS7006 hatasıdır (Parameter 's' implicitly has an 'any' type), bu yüzden onlara notasyon yazın. Ve çalışma zamanında hiçbir iz bırakmaz, bu yüzden obj instanceof Shape mümkün değildir.

Constructor'daki private radius bir parametre özelliğidir (parameter property): alanı tek adımda bildirir ve atar. Bkz. constructor'lar.

Bir Sınıf Aynı Zamanda Bir Tiptir

Bir sınıf bildirimi tek bir adla iki şey oluşturur: bir değer (new ile çağırdığınız constructor fonksiyonu) ve bir tip (bir örneğin biçimi). TypeScript tipleri yapıya göre karşılaştırdığı için, aynı public üyelere sahip her nesne, sınıf tarafından oluşturulmamış olsa bile tipe uyar.

Düz nesne tip kontrolünden geçer ama çalışma zamanında bir Point değildir: ({ x: 6, y: 8 }) instanceof Point sonucu false olur. private veya #private bir üyeye sahip bir sınıf bunu engeller: ona yalnızca o sınıfın (ya da alt sınıflarının) örnekleri atanabilir.

Sık Yapılan Hatalar

  • Bir alanı bildirip hiç atamamak. TS2564 size alanın undefined olacağını söylüyor. Onu ! ile susturmak yerine başlatın.
  • Bir metodu callback olarak vermek. button.onclick = obj.handle, this değerini kaybeder. Bir arrow function alanı ya da obj.handle.bind(obj) kullanın.
  • implements ifadesinin kod ya da tip eklemesini beklemek. Yalnızca kontrol eder. Parametre tipleri yine notasyon ister.
  • instanceof ifadesini bir interface ile kullanmak. Interface'ler çalışma zamanında yoktur; bir sınıfı kontrol edin ya da bir type guard kullanın.
  • Tiplerin veriyi doğruladığını varsaymak. Bir number alanı derleme zamanında her sayıyı, çalışma zamanında da tipsiz veriden gelen her şeyi kabul eder.

Sıkça Sorulan Sorular

TypeScript'te bir sınıf nasıl oluşturulur?

Sınıf gövdesinde her alanı tipiyle bildirin, ardından constructor'ı ve metotları JavaScript'teki gibi yazın: class User { name: string; constructor(name: string) { this.name = name; } greet(): string { return "Hi, " + this.name; } }. Bir örneği new User("Ada") ile oluşturun.

"has no initializer and is not definitely assigned in the constructor" ne anlama gelir?

strictPropertyInitialization (strict kapsamında) kaynaklı TS2564 hatasıdır. string olarak tiplenmiş bir alan, onu hiçbir şey ayarlamadığı için undefined olarak başlardı. Bunu bir başlangıç değeriyle (name = ""), constructor içinde bir atamayla, opsiyonel bir alanla (name?: string) ya da onu constructor dışında bir şey ayarlıyorsa bir kesin atama assertion'ıyla (name!: string) düzeltin.

TypeScript'te implements ile extends arasındaki fark nedir?

extends bir ebeveyn sınıftan kod miras alır: alanları ve metotları çalışma zamanında çocukta vardır. implements ise yalnızca derleyiciden sınıfın bir interface'in biçimine sahip olduğunu kontrol etmesini ister. Sınıfa hiçbir şey eklemez ve derlenmiş JavaScript'ten kaybolur.

TypeScript'te bir sınıf tip olarak kullanılabilir mi?

Evet. Bir sınıf adı hem bir değerdir (constructor) hem de bir tiptir (örneklerinin biçimi). let u: User, aynı public üyelere sahip her nesneyi kabul eder, çünkü TypeScript tipleri yapısal olarak karşılaştırır. typeof User ise constructor'ın kendisinin tipidir.

TypeScript sınıfları çalışma zamanında JavaScript sınıflarından farklı mıdır?

Hayır. TypeScript bir sınıfı normal bir JavaScript sınıfına derler. Tip notasyonları, implements ifadeleri ve private gibi belirleyiciler silinir; çalışma zamanında yalnızca #private alanlar, static bloklar ve getter'lar gibi JavaScript özellikleri vardır.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA