TypeScript'te tip güvenliği nerede biter
any kullanmamak tip güvenliği demek değil. Derleyicinin size yalan söylediği yerler ve sınırı gerçekten kapatmanın yolu.
TypeScript ile çalışan ekiplerde yaygın bir yanılgı var: any kullanmıyorsak tip güvendeyiz. Oysa TypeScript'in tip denetimi yalnızca derleme zamanında çalışıyor ve çalışma zamanında hiçbir garantisi yok.
Bu, derleyicinin size sessizce yalan söyleyebileceği bir dizi sınır anlamına geliyor. Sınırların hepsi bilinen ve kapatılabilir — ama kapatılması gerektiğini bilmek gerekiyor.
Sınır 1: Sistemin dışından gelen her şey
Bu en büyüğü. Ağdan gelen bir yanıtı bir tiple işaretlediğinizde, TypeScript bunu doğrulamaz; sadece kabul eder.
type Kullanici = { id: number; ad: string };
const yanit = await fetch("/api/kullanici");
const kullanici: Kullanici = await yanit.json(); // ← burada hiçbir kontrol yok
Sunucu ad alanını göndermezse, kullanici.ad çalışma zamanında undefined olur ama derleyici bunu string sanmaya devam eder. Hata, o değeri kullandığınız yerde — genelde tamamen başka bir dosyada — patlar.
Aynı durum şunların hepsi için geçerli: JSON.parse, localStorage, ortam değişkenleri, URL parametreleri, form verisi, veritabanı sürücüsünün döndürdüğü ham satırlar, üçüncü taraf kütüphanelerin tip tanımları.
Çözüm: Sınırda çalışma zamanı doğrulaması. Zod, Valibot, ArkType gibi kütüphaneler bir şemadan hem doğrulayıcı hem TypeScript tipi üretiyor:
const KullaniciSemasi = z.object({ id: z.number(), ad: z.string() });
type Kullanici = z.infer<typeof KullaniciSemasi>;
const kullanici = KullaniciSemasi.parse(await yanit.json());
// buradan sonrası gerçekten güvenli
Kural: Doğrulama, sisteme giriş noktasında bir kez yapılır; içeride bir daha yapılmaz. İçeride tekrar tekrar kontrol eden kod, sınırın kapatılmadığının işaretidir.
Sınır 2: Tip zorlaması (as)
as bir dönüştürme değil, bir emirdir: "bu değeri şu tip say." Derleyici uyar.
const eleman = document.querySelector(".dugme") as HTMLButtonElement;
// eleman yoksa null'dur, ama derleyici artık öyle düşünmüyor
as kullanımlarının çoğu aslında any'nin kibar hâli. Kabul edilebilir olduğu durumlar dar: test verisi, gerçekten dışarıdan garanti edilen bir durum, ya da tip sisteminin ifade edemediği bir daralma. Bunların dışında as gördüğünüzde, altında doğrulanmamış bir varsayım var demektir.
Sınır 3: Dizi ve nesne erişimi
Varsayılan ayarlarla:
const liste: string[] = [];
const ilk = liste[0]; // tipi string — ama değeri undefined
ilk.toUpperCase(); // çalışma zamanı hatası, derleme temiz
Bunu düzelten ayar noUncheckedIndexedAccess. Açıldığında liste[0] tipi string | undefined olur ve derleyici sizi kontrole zorlar. Çoğu projede varsayılan olarak kapalı; açmak mevcut kodda çok sayıda hata gösterir — ki bu, o hataların zaten orada olduğu anlamına gelir.
tsconfig.json tarafında en azından şunlar açık olmalı:
{
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
Sınır 4: Yapısal tipleme aynı şekilli şeyleri karıştırır
TypeScript tipleri isme göre değil şekle göre karşılaştırır. KullaniciId ve SiparisId ikisi de number ise, birbirinin yerine geçebilir ve derleyici itiraz etmez.
function siparisGetir(siparisId: number) { ... }
siparisGetir(kullanici.id); // derleyici mutlu, sistem yanlış
Çözüm, markalı tipler (branded types):
type SiparisId = number & { readonly __marka: "SiparisId" };
Ekstra bir çalışma zamanı maliyeti yok, ve bu hata sınıfını tamamen ortadan kaldırıyor. Kimlik türlerinin karıştığı sistemlerde — çok kiracılı uygulamalarda özellikle — değerli.
Sınır 5: Object.keys ve benzerleri yalan söyler
const nesne = { a: 1, b: 2 };
Object.keys(nesne); // tipi string[], "a" | "b" değil
Bu kasıtlı bir tasarım kararı: nesnede tip tanımında olmayan ek alanlar olabilir. Yani TypeScript burada aslında dürüst davranıyor — ama çoğu geliştirici tersini bekliyor ve döngü içinde tip hatası alıyor.
Pratik kontrol listesi
strict: truevenoUncheckedIndexedAccess: true.- Sisteme giren her veri, giriş noktasında bir şemayla doğrulanıyor.
askullanımları sayılabilir kadar az ve her biri gerekçeli.- Kimlik tipleri markalı.
- Üçüncü taraf tip tanımlarına, kendi kodunuz kadar güvenmiyorsunuz.
Bunların hiçbiri TypeScript'i "gerçekten tip güvenli" yapmıyor — dilin çalışma zamanı hâlâ JavaScript. Ama yaptığı şey daha faydalı: hataların ortaya çıktığı yeri, kullanıldığı noktadan sisteme girdiği noktaya taşıyor. Bir hatanın nerede ortaya çıktığı, hata ayıklama süresinin neredeyse tamamını belirliyor.
- typescript
- tip sistemi
- doğrulama
- javascript