TypeScript'in yeni const type parameter sözdizimi, çağırıcıları her yere as const serpiştirmeye zorlamadan bir fonksiyonun literal türleri bozulmadan korumasını sağlar ve en yaygın tür genişlemesi (type-widening) hatalarının kaynağını ortadan kaldırır.

Generic kodların peşini bırakmayan genişleme (widening) problemi

Generic bir fonksiyon bir nesne literal'i (object literal) aldığında, derleyici herhangi bir literal özelliği daha geniş bir ilkel (primitive) türe genişletir.

function call<T>(arg: T) {}
call({ method: "GET" })   // T is inferred as { method: string }

"GET" literal'i string türüne dönüşür. Ayrılmış birlikler (discriminated unions) veya template-literal çıkarma gibi tam değere bağımlı olan sonraki kodlar bozulur; çünkü tür artık kesin literal bilgisini taşımaz. Geliştiriciler uzun süredir bu sorunu, çağrı noktasında { method: "GET" } as const yazarak aşmaya çalışıyorlardı; bu, derleyiciye literal'i korumasını söyler ancak bu çözüm fonksiyonun tanımında değil, çağırıcının elindedir.

Const type parametreleri: imza düzeyinde bir çözüm

Bir tür parametresi üzerindeki yeni const değiştiricisi, derleyiciye o generic argüman için mümkün olan en dar (narrowest possible) türü tahmin etmesini (infer) söyler. Bir fonksiyonu function foo<const T>(arg: T) şeklinde tanımlamak, T'nin sanki çağırıcı as const yazmış gibi davranmasını sağlar.

  • String, number, boolean literal'leri tam değerlerini korur (string yerine "GET").
  • Diziler (Arrays), her bir öğesi kesin olarak türlendirilmiş salt okunur (readonly) tuple'lara dönüşür.
  • Nesneler (Objects), her iç içe geçme seviyesinde literal türleri koruyan derinlemesine salt okunur yapılara dönüşür.

Kısıtlama fonksiyon imzasında yer aldığı için her çağırıcı otomatik olarak bundan yararlanır; bir tür dönüşümünü (cast) unutmak artık tür güvenliğinin bozulmasına yol açmaz.

Neden klasik as const hilesinden daha iyi?

as const çağırıcı tarafında (caller-side) bir çözümdür. Generic bir fonksiyonu kullanan herkesin bu assertion'ı (doğrulamayı) eklemeyi hatırlamasını gerektirir. Tek bir çağrıyı bile kaçırırsanız, tür güvenliği yok olur. Const type parametresi sorumluluğu doğrudan API tasarımına taşır: fonksiyon "geçtiğiniz şeyin mümkün olan en dar biçimine ihtiyacım var" der ve derleyici bunu uygular.

Bu değişim, en çok generic builder'lar, konfigürasyon fabrikaları veya bir alanın literal değerinin tür mantığını yönlendirdiği herhangi bir API sunan kütüphaneler ve yardımcı araçlar için önemlidir. Kütüphane yazarı, sonraki kodları denetlemek zorunda kalmadan doğru çıkarımı (inference) garanti edebilir.

Fayda sağlayan gerçek dünya senaryoları

  • Konfigürasyon oluşturucular (Configuration builders) – ortam adları ("dev" | "prod") literal olarak kalır ve ek dönüşümler gerektirmeden ayrılmış birlik (discriminated-union) kontrollerine olanak tanır.
  • API rota tanımları – yol dizeleri (path strings) tam haliyle kalır, böylece template-literal türleri parametreleri çıkarabilir ("/users/:id"\/users/${string}``).
  • Durum makinesi (State-machine) yardımcıları – durum tanımlayıcıları, metod zincirleme (method chaining) yoluyla sabit literal'ler olarak kalır ve kazara durum uyuşmazlıklarını önler.

Her durumda, const parametresi tekrarlanan as const kalıplarını (boilerplate) ortadan kaldırır ve sinsi hataların araya sızma olasılığını azaltır.

satisfies operatörü ile birlikte kullanımı

satisfies operatörü, bir değerin orijinal literal bilgisini korurken yapısal bir türe uygun olup olmadığını doğrular. Her ikisini birlikte kullanmak her iki dünyanın da en iyisini sunar: const parametreleri dar çıkarım (narrow inference) sağlar, satisfies ise değerin gereken biçime uygun olmasını sağlar.

function makeConfig<const C>(cfg: C) {
  // cfg is inferred with exact literals
}
const cfg = {
  env: "staging",
  ports: [8080, 8443],
} satisfies { env: string; ports: number[] };
makeConfig(cfg); // works, literals stay intact

Ne zaman as const kullanılmalı?

Const parametresi, fonksiyonun imzasını kontrol ettiğinizde parlar. Eğer bu değiştiriciye sahip olmayan üçüncü taraf fonksiyonlarla uğraşıyorsanız veya yerel bir değişken için tek seferlik bir literal korumasına ihtiyacınız varsa, as const doğru araç olmaya devam eder. Çağrılan API'yi değiştirmeden bir değeri dondurmak için hala temel yöntemdir.

Sırada ne var?

Özellik henüz çok yeni, bu nedenle araçlar ve topluluk kalıpları gelişmeye devam ediyor. Yeni sözdizimini otomatik tamamlama ve hızlı düzeltme önerilerinde sunan IDE desteği güncellemeleri bekleyin. Kütüphane yöneticilerini takip edin: birçoğu genel (public) generic yapıları const parametrelerine taşımaya başlayacaktır; bu da daha önce açık as const dönüşümlerine güvenen kodlar için kırıcı değişikliklere (breaking changes) yol açabilir.

Özet: TypeScript'in const type parametreleri, literal korumasını doğrudan bir fonksiyonun tür parametrelerine gömerek yaygın bir genişleme hatası kaynağını ortadan kaldırır ve güvenliği çağırıcıdan tekrar API tasarımcısına aktarır. Sahibi olduğunuz tüm generic giriş noktaları için bunları kullanın; as const kullanımını ise yerel değerler veya harici API'ler için saklayın.