Birçok nesneye dayalı dille karşılaştırıldığında, TypeScript yapısal tiplemeyi (duck typing) uygular: Bir nesne, gerekli tüm özelliklere sahipse, bu türde kabul edilir; türün açıkça tanımlanıp tanımlanmadığına bakılmaksızın.
Bu esneklik, bazen yapının uyuştuğu durumlarda nesnelerin tür olarak yanlış kabul edilmesine yol açabilir, oysa aslında anlam açısından bağlantılı değillerdir. Bu, yapının tesadüfen eşleştiği karmaşık veri modellerinde tehlikeli olabilir.
Nesne türlerini her zaman doğru yapılandırın, farklı varlıkların yapısal uyuşumlarını en aza indirin, kritik durumlarda türleri "nominalleştirmek" için ek özellikler veya semboller kullanın.
Kod örneği:
interface Point { x: number; y: number; } interface Pixel { x: number; y: number; } function drawPoint(p: Point) { console.log(p.x, p.y); } const pixel: Pixel = { x: 1, y: 2 }; drawPoint(pixel); // TAMAM, türler yapısal olarak uyumlu
Ana özellikler:
İki arayüzün yapısı uyuşuyorsa, bu onların tamamen birbirinin yerini alabileceği anlamına mı gelir?
Yapı itibarıyla öyle olabilir, ama programın mantığı açısından değil. Bu, derleyici düzeyinde kabul edilebilir, ancak mantıksal hatalara yol açabilir (örneğin, yukarıdaki Point ve Pixel).
Bir tür için yapısal uyumluluğu yasaklamak mümkün mü?
Tamamen hayır, ancak benzersiz bir özellik ekleyebilirsiniz (örneğin, sembolle):
interface Brand { _brand: unique symbol; }
Artık başka bir nesne bu türü taklit edemez, aynı benzersiz sembol olmadan.
Yapısal tipleme, nominal tiplemeden nasıl farklıdır?
Yapısal — yapının varlığına, nominal — belirli bir namespace'deki tür adının uyuşumuna dayanır. TS'de varsayılan olarak her zaman yapısal tipleme vardır.
Bazı nesnelerde yanlışlıkla alanlar uyuştu (örneğin, User ve Admin olarak {id: number, name: string}), bu da API sözleşmeleriyle çalışırken kafa karışıklığına yol açtı.
Artılar:
Eksiler:
Anlam açısından farklı yapıların ayırt edilmesi için benzersiz "etiketler" ve standart dışı alanlar kullanımı.
Artılar:
Eksiler: