İçeriğe geç
edumintsBlog
Web & Frontend3 dk okuma

TypeScript Kodunuz Canlı Ortamda Neden Hâlâ Çöküyor?

Kaynak: dev.to

Paylaş
İçindekiler 3 başlık

Bütün bir öğleden sonrayı projenize tipler ekleyerek geçirdiniz. Her değişkenin bir interface'i var, her fonksiyonun dönüş tipi açıkça belirtilmiş ve editörünüzde tek bir kırmızı hata çizgisi dahi yok. Kendinizi yenilmez hissederek kodunuzu canlı ortama (production) dağıtıyorsunuz. Ancak yirmi dakika sonra hata izleyicinizden o can sıkıcı bildirim düşüyor:

TypeError: Cannot read properties of undefined (reading 'toUpperCase')

Peki bu nasıl olabilir? TypeScript tam olarak bu hatayı imkânsız kılmak için tasarlanmamış mıydı? Eğer bu senaryoyu yaşadıysanız kulübe hoş geldiniz. Neredeyse her yazılımcı, TypeScript'in sürekli bağıran bir yardımcı pilot gibi hissettirdiği ancak gerçek hataların canlı ortama sızmasını engelleyemediği bir öğrenme evresinden geçer. Buradaki temel sorun yazdığınız kod değil; kurduğunuz zihinsel modeldir (mental model). Yeni başlayanların çoğu TypeScript'i JavaScript'in üzerine monte edilmiş Java veya C# gibi görür. Oysa TypeScript geleneksel dillerden tamamen farklı çalışır. Derleyiciyle savaşmayı bırakmak için bu sistemin gerçekte nasıl düşündüğünü anlamamız gerekir.

1. Hayalet Tip Sistemi: Tip Silinmesi (Type Erasure)#

TypeScript ile ilgili öğrenilmesi gereken en kritik gerçek şudur: Kodunuz çalışırken TypeScript diye bir şey yoktur.

TypeScript derleyicisi (tsc) çalıştığında iki bağımsız işlem yürütür:

  • Kodunuzu tip hatalarına karşı denetler.
  • Tanımladığınız her bir type, interface ve tip ek açıklamasını tamamen silerek geriye saf JavaScript bırakır.

Derleme tamamlandıktan sonra o özenle tasarladığınız arayüzler ve generic kısıtlamalar tamamen yok olur. Node.js veya tarayıcının V8 motoru sadece ham JavaScript çalıştırır; çalışma zamanının (runtime) hangi tipleri yazdığınıza dair hiçbir hafızası yoktur.

Başlangıç Tuzağı ve Dış Veri Tehlikesi#

Tiplerin çalışma zamanında var olduğunu sanan geliştiriciler sıklıkla if (data instanceof User) gibi kontroller yazar. Ancak User bir arayüzdür ve derleme aşamasında silinmiştir. Bellekteki prototipleri denetleyen instanceof operatörü için bu kontrol runtime'da anlamsızdır ve hata üretir.

Aynı yanılgı dış dünyadan gelen verilerde de geçerlidir. Bir API çağrısında (await response.json()) as ApiResponse yazdığınızda derleyiciye "bana güven" dersiniz. Oysa TypeScript ağ trafiğini izleyemez; sunucu { error: "User not found" } döndürdüğünde uygulamanız canlıda patlar.

  • Pratik Çıkarım: TypeScript sizin yazdığınız kodu doğrular; dış dünyanın size gönderdiği veriyi değil. API yanıtları ve kullanıcı girdileri gibi dış sınırlarda tip zorlaması (as) yerine Zod gibi çalışma zamanı şema doğrulayıcıları veya özel type guard fonksiyonları kullanın.

2. İsim Yerine Şekil: Yapısal Tipleme (Structural Typing)#

Java, C# veya C++ gibi dillerden geliyorsanız bu kavram bakış açınızı tamamen değiştirecektir. Geleneksel diller isim tabanlı (nominal) tipleme kullanırken, TypeScript nesnelerin adlarına değil, sahip oldukları yapıya ve şekle bakar. İki farklı tip aynı alanlara sahipse, TypeScript onları birbiriyle uyumlu kabul eder. Bu durum esneklik sağlasa da çalışma zamanında doğru modellenmediğinde beklenmedik bug'lara yol açabilir.

Kaynak ve atıf

Bu yazı, dev.to üzerinde yayımlanan içerikten yararlanılarak Edumints tarafından yapay zekâ desteğiyle Türkçe hazırlandı. Ayrıntılar ve yazarların kendi anlatımı için orijinaline bakabilirsin:

  • dev.to/smtahosin/why-your-typescript-code-still-crashes-in-production-2bf4