TypeScript’te iki dil var
TypeScript yazarken aslında iki dil kullanıyorsun. Biri bildiğin JavaScript: Tarayıcıda ya da Node’da çalışan değerler. Diğeri tip dili: Sadece derleme sırasında, tsc ya da editörün içinde çalışıyor ve sonra tamamen siliniyor.
Tip dili sandığından güçlü. Koşul (A extends B ? X : Y), desen yakalama (infer), kendini çağıran tipler ve metin şablonları var. Bunlarla hesap yapabiliyorsun. Mesela iki sayıyı, dizilerin uzunluğu üzerinden toplamak:
type Dizi<N extends number, A extends unknown[] = []> =
A['length'] extends N ? A : Dizi<N, [...A, unknown]>;
type Topla<A extends number, B extends number> =
[...Dizi<A>, ...Dizi<B>]['length'];
type Bes = Topla<2, 3>; // 5
Koşul ve kendini çağırma bir araya gelince sistem Turing tam (Turing complete) oluyor. Yani yeterli zaman ve bellek verirsen, her hesaplanabilir şeyi hesaplayabiliyor. Bu fikrin kökünü Turing’den GPT-3’e uzanan makaleler yazımızda anlattık.
DOOM tiplerde nasıl çalıştı?
Mitropoulos DOOM’u tiplerle baştan yazmadı. Daha akıllıca bir yol seçti: Tiplerin içinde bir WebAssembly çalıştırıcısı yazdı. DOOM zaten C ile yazılmış ve WebAssembly’ye derlenebiliyor. Projenin README’sine göre tip sistemi bu talimatları tek tek işliyor. Ortada hiç JavaScript kodu yok. Bölümde anlattığına göre çıktı, her pikselin iki karakterle gösterildiği gri tonlu bir metin resmi.
Rakamlar abartılı. Socket’in haberine göre çalıştırıcı DOOM’un ihtiyaç duyduğu 116 WebAssembly talimatını uyguluyor. İlk kareyi çizmek için tip denetleyicisi 12 gün boyunca saniyede yaklaşık 20 milyon tip örneği (instantiation) üretti. Toplamda 177 TB tip verisi işlendi. Bunun için derleyicideki güvenlik sınırlarını, örneğin özyineleme derinliği limitini, geçici olarak kaldırmak gerekti. Sayılar bile tiplerde ikilik sistemde, metin olarak tutuluyor. Mitropoulos’a göre iş bir buçuk yıl sürdü.
Bu sana neden önemli?
Çünkü DOOM’u yavaşlatan şey, senin projeni de yavaşlatan şeyle aynı. Mitropoulos bölümde gerçek örneklerden bahsediyor: Tip kontrolü için onlarca GB bellek isteyen büyük monorepolar, birbiriyle çarpılıp patlayan birleşim (union) tipleri. Bir de yaygın bir alışkanlık var: “Type instantiation is excessively deep” hatasını @ts-expect-error ile susturmak. Kırmızı çizgi kayboluyor ama bedel ödenmeye devam ediyor.
İki pratik ders var:
- Ölç, tahmin etme. Mitropoulos’un yazdığı TypeSlayer,
npx typeslayerile açılıyor. TypeScript’in iz (trace) dosyalarını ve CPU profillerini toplayıp en büyük birleşim tiplerini ve sınıra takılan yerleri görsel olarak gösteriyor. Bölüme göre tek bir beş satırlık düzeltme bir CI hattından 100 saniye kazandırdı. - Kendini çağıran tipleri kuyruktan çağır. TypeScript 4.5’ten beri bir koşul tipinin dalı doğrudan kendini çağırıyorsa ara sonuçlar tutulmuyor ve sınırlar çok daha cömert. Sonucu bir birikim (accumulator) parametresinde taşımak, aynı tipi çok daha uzun girdilerde çalıştırabiliyor. Yukarıdaki
Dizitipi bu kalıpta yazılmış.
Sonra ne oldu?
TypeScript 7.0, 8 Temmuz 2026’da çıktı. Derleyici Go diline taşındı ve Microsoft’a göre tam derlemeler 8–12 kat hızlandı. Bunu Bun ve TypeScript 7 yazımızda anlattık. Ama tip kontrolünün mantığı 6.0 ile aynı kaldı: Pahalı bir tip hâlâ pahalı, sadece daha hızlı hesaplanıyor. Mitropoulos bölümde bunu yola şerit eklemeye benzetiyordu. Trafik rahatlıyor, sonra yine doluyor.
Düşün
- Projende en karmaşık tip hangisi? Onu bir haftalık yeni bir ekip arkadaşı okuyabilir mi?
- Bir tip hatasını susturmak ile tipi sadeleştirmek arasında ne zaman hangisini seçersin?
Videoyu izle
Kaynaklar (8, İngilizce)
- Syntax #969: This guy is nuts (TypeScript Doom) (yeni sekmede açılır)
- Syntax: This Guy Broke TypeScript (video) (yeni sekmede açılır)
- Michigan TypeScript: Doom in TypeScript types (video) (yeni sekmede açılır)
- GitHub: MichiganTypeScript/typescript-types-only-wasm-runtime (yeni sekmede açılır)
- Socket: Michigan TypeScript founder successfully runs Doom inside TypeScript's type system (yeni sekmede açılır)
- TypeScript 4.5 release notes: Tail-recursion elimination on conditional types (yeni sekmede açılır)
- GitHub: dimitropoulos/typeslayer (yeni sekmede açılır)
- TypeScript Blog: Announcing TypeScript 7.0 (yeni sekmede açılır)
Kendi cümlelerimizle yazılmış bir özettir, çeviri değildir. Tüm kaynaklar yukarıda.