Bu fikri eskiden bilerek daha iddialı ifade ediyordum: Codex için en iyi dil TypeScript. Bugün daha doğru söylerdim. Benim yaptığım üretim odaklı frontend ve full-stack geliştirmede TypeScript, Codex'i kontrol etmenin, doğrulamanın ve güvenle kullanmanın en kolay olduğu ortam.
Buradaki kritik kelime “TypeScript” değil, kontrol. AI kodlama ajanları ikna edici görünen kod üretmekte çok iyi. Üretim mühendisliği ise daha fazlasını ister: kod mevcut sözleşmelere uymalı, davranışı korumalı, refactor'lardan sağ çıkmalı ve bir varsayım yanlışsa erken hata vermelidir. TypeScript bu kısıtların çok daha fazlasını saf JavaScript'e göre makine tarafından okunabilir hâle getirir.
Codex'in bir codebase'den gerçekten ihtiyacı olan şey
İyi prompt faydalıdır ama bağlamın yalnızca bir parçasıdır. Codebase'in kendisi görevi açıklayabilir veya modeli tahmin etmeye zorlayabilir. Pratikte en güçlü ortam, önemli varsayımların görünür ve otomatik olarak doğrulanabilir olduğu ortamdır.
- Fonksiyon imzaları geçerli giriş ve çıkışları tanımlar.
- Interface ve type'lar domain nesnelerinin şeklini açık eder.
- Union ve enum'lar geçerli durum kümesini daraltır.
- Derleyici birçok yanlış varsayımı düzenlemeden hemen sonra somut hataya dönüştürür.
Uygulama bir sözleşme bozulduğu anda geri bildirim verebiliyorsa, AI ajanının tüm sistemi kusursuz anlaması gerekmez. Feedback loop ne kadar kısa olursa, kendinden emin tahminlere o kadar az alan kalır.
Type'lar sadece dokümantasyon değil, çalıştırılabilir bağlamdır
İyi TypeScript insanlara tasarım niyetini anlatır. Otomatik bir workflow'da daha da değerlidir, çünkü bu dokümantasyon doğrulanabilir. Örneğin:
type PaymentResult =
| { ok: true; receiptId: string }
| { ok: false; code: "declined" | "timeout" };
function getReceiptId(result: PaymentResult) {
if (result.ok) return result.receiptId;
return result.receiptId;
// TypeScript: Property 'receiptId' does not exist
// on the failure branch.
}JavaScript'te aynı hata ilgili branch runtime'da çalışana kadar mantıklı görünebilir. TypeScript ise yanlış varsayımı merge'den önce reddedebilir. Codex açısından compiler error yalnızca editördeki kırmızı çizgi değil, modelin neyi yanlış anladığını anlatan net bir sinyaldir.
Bu nedenle Record<string, any> gibi geniş yapılar yerine açık domain type'larını tercih ediyorum. Type'lar gerçekliği ne kadar iyi anlatırsa codebase hem geliştirici hem AI için o kadar iyi bağlam olur.
Derleyici hataları feedback loop'a dönüştürür
“Codex'e kod yazdır ve ilk cevabı kabul et” yaklaşımına güvenmiyorum. Süreç iteratiftir:
task → inspect → edit → typecheck → lint → test → review diffBu akış sıkıcıdır ve tam da bu yüzden çalışır. Her anlamlı değişiklikten sonra ortam cevap verir. Type errors bozuk sözleşmeleri bulur. Lint başka bir problem sınıfını yakalar. Testler type sisteminin ifade edemediği davranışı kontrol eder. Son diff yine insan tarafından incelenir.
Akıllı bir prompt ilk denemeyi iyileştirebilir. Güçlü doğrulama döngüsü ise her denemeyi iyileştirir. Üretimde daha önemli olan budur.
Büyük refactor'larda TypeScript'in değeri daha da artar
Küçük ve izole değişiklikler neredeyse her coding assistant için kolaydır. Zor olan, değişikliğin onlarca dosyaya yayıldığı durumdur: domain alanını yeniden adlandırmak, API response'u değiştirmek, component prop'larını sıkılaştırmak, union'ı bölmek veya eski bir abstraction'ı değiştirmek.
TypeScript'te breaking change etkilenen varsayımların bir haritasını çıkarır. Derleyici eski sözleşmenin hâlâ kullanıldığı yerleri gösterir. Codex bu listeyi sırayla düzeltebilir ve her turdan sonra tekrar doğrulama yapılabilir. Bu büyük refactor'u otomatik olarak doğru yapmaz ama blast radius'u görünür kılar.
Gevşek tipli bir projede gözden kaçan dependency bazen ilk kez geliştirme sırasında kimsenin açmadığı bir ekranda bug olarak ortaya çıkar.
TypeScript'in koruyamadığı şeyler
TypeScript bir guardrail'dir, doğruluk kanıtı değildir:
- Yanlış business logic: kusursuz tipli kod yine de yanlış sonucu hesaplayabilir.
- Runtime veri: API, veritabanı, form veya üçüncü taraf servis compile-time varsayımından farklı veri döndürebilir.
- Eksik ürün bağlamı: derleyici bir flow'un neden var olduğunu veya hangi edge case'in kullanıcı için kritik olduğunu bilmez.
- Güvenlik ve mimari: geçerli type'lar doğru authorization, caching, database sınırları veya altyapıyı garanti etmez.
Bu yüzden runtime validation, testler, logging, observability ve review hâlâ gereklidir. Temiz typecheck, feature'ın doğru olduğu anlamına gelmez.
AI destekli değişikliklerde kullandığım workflow
- Dar bir hedef tanımlarım. Ne değişecek, ne değişmeyecek ve acceptance criteria nedir?
- Codex'in edit'ten önce inceleme yapmasını isterim. Mevcut type'lar, call site'lar, testler ve komşu modüller çoğu zaman uzun prompttan daha değerlidir.
- En küçük tutarlı değişikliği tercih ederim. Odaklı diff, alakasız kodu “iyileştiren” rewrite'tan daha kolay doğrulanır.
- Hemen typecheck ve lint çalıştırırım. Yapısal hataları değişiklik hâlâ küçükken görmek isterim.
- İlgili testleri çalıştırır, davranış değişirse test eklerim. Type'lar sözleşmeleri, testler davranışı doğrular.
- Son diff'i elle incelerim. İsimlendirme, mimari, tekrar, edge case'ler ve asıl problemin gerçekten çözülüp çözülmediği.
JavaScript'in hâlâ yeterli olduğu yerler
Bu, JavaScript kötüdür demek değil. Küçük script, atılabilir prototip, basit otomasyon veya az shared state içeren kodda TypeScript'in ek yapısı çok az fayda sağlayabilir. İyi testleri ve net convention'ları olan JavaScript projesi de AI için güçlü bir ortam olabilir.
Benim iddiam daha dar: codebase büyüdükçe, uzun ömürlü ve daha ortak hâle geldikçe makine tarafından doğrulanabilir kısıtların değeri artar. AI hatalarının maliyeti de tam bu noktada yükselir.
Codex ile TypeScript'i tercih etmemin gerçek nedeni
TypeScript Codex'i daha zeki yapmaz. Ortamı kötü varsayımlara karşı daha az toleranslı yapar.
Üretimde yalnızca yaratıcı bir ajan değil, yanlış yaptığı anda sürekli geri bildirim alan bir ajan istiyorum. Type'lar, compiler errors, lint, testler ve insan review'u birlikte bu sistemi oluşturur.
Bu yüzden TypeScript'in Codex ile çok iyi çalıştığını söylerken dil fanatizminden bahsetmiyorum. Hızlı ve makine tarafından doğrulanabilir feedbackten bahsediyorum: daha az belirsizlik, daha küçük blast radius, daha güvenli refactor'lar ve doğrulama ciddiye alındığında daha güvenilir mühendislik hızı.