Sintaks const type parameter baru di TypeScript memungkinkan sebuah fungsi menjaga tipe literal tetap utuh tanpa memaksa pemanggil untuk menyebar as const di mana-mana, sehingga mengurangi sumber bug type-widening yang paling umum.

Masalah widening yang menghantui kode generik

Ketika sebuah fungsi generik menerima object literal, kompiler akan memperluas (widen) properti literal apa pun ke tipe primitifnya yang lebih luas.

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

Literal "GET" menyusut menjadi string. Kode hilir (downstream) yang bergantung pada nilai yang tepat—seperti discriminated unions atau ekstraksi template-literal—akan rusak karena tipenya tidak lagi membawa literal yang presisi. Pengembang telah lama menyiasati hal ini dengan menulis { method: "GET" } as const pada lokasi pemanggilan, yang memberi tahu kompiler untuk menjaga literal tersebut, tetapi perbaikan itu berada di tangan pemanggil, bukan pada definisi fungsinya.

Const type parameters: perbaikan di tingkat signature

Modifikator const baru pada parameter tipe memberi tahu kompiler untuk menyimpulkan (infer) tipe yang paling sempit yang memungkinkan untuk argumen generik tersebut. Mendeklarasikan fungsi sebagai function foo<const T>(arg: T) membuat T secara otomatis berperilaku seolah-olah pemanggil telah menulis as const.

  • Literal string, number, boolean tetap pada nilai tepatnya ("GET" alih-alih string).
  • Array menjadi readonly tuple dengan setiap elemen yang bertipe presisi.
  • Objek berubah menjadi struktur deeply readonly, menjaga tipe literal di setiap tingkat sarang (nesting level).

Karena batasan tersebut berada di dalam function signature, setiap pemanggil akan mendapat manfaat secara otomatis; melupakan cast bukan lagi jalan menuju ketidakamanan tipe (unsoundness).

Mengapa ini lebih baik daripada trik as const klasik

as const adalah solusi di sisi pemanggil (caller-side). Ini mengharuskan setiap konsumen fungsi generik untuk ingat menambahkan asersi tersebut. Lewatkan satu pemanggilan saja, dan keamanan tipe akan menguap. Const type parameter memindahkan tanggung jawab ke dalam desain API itu sendiri: fungsi tersebut menyatakan “Saya butuh bentuk paling sempit dari apa pun yang Anda berikan,” dan kompiler akan menegakkannya.

Pergeseran tersebut sangat penting bagi pustaka (library) dan utilitas yang mengekspos generic builders, pabrik konfigurasi (configuration factories), atau API apa pun di mana nilai literal dari sebuah bidang menggerakkan logika tipe. Penulis pustaka dapat menjamin inferensi yang benar tanpa harus mengawasi kode hilir (downstream code).

Skenario dunia nyata yang diuntungkan

  • Configuration builders – nama lingkungan ("dev" | "prod") tetap literal, memungkinkan pemeriksaan discriminated-union tanpa cast tambahan.
  • Definisi rute API – string jalur tetap tepat, memungkinkan tipe template-literal untuk mengekstrak parameter ("/users/:id"\/users/${string}``).
  • Helper state-machine – pengidentifikasi status tetap berupa literal tetap melalui perantaian metode (method chaining), mencegah ketidakcocokan status yang tidak disengaja.

Dalam setiap kasus, parameter const menghilangkan boilerplate as const yang berulang dan mengurangi kemungkinan bug halus lolos.

Dipasangkan dengan operator satisfies

Operator satisfies memvalidasi bahwa sebuah nilai sesuai dengan tipe struktural sambil tetap menjaga informasi literal aslinya. Menggunakan keduanya secara bersamaan memberikan yang terbaik dari kedua dunia: parameter const memberikan inferensi yang sempit, dan satisfies memastikan nilai tersebut memenuhi bentuk yang diperlukan.

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

Kapan harus tetap menggunakan as const

Parameter const sangat berguna ketika Anda mengontrol function signature-nya. Jika Anda berurusan dengan fungsi pihak ketiga yang tidak memiliki modifikator tersebut, atau Anda memerlukan pelestarian literal sekali pakai untuk variabel lokal, as const tetap menjadi alat yang tepat. Ia tetap berfungsi sebagai cara utama untuk membekukan nilai tanpa mengubah API yang dipanggil.

Apa yang perlu diperhatikan selanjutnya

Fitur ini masih baru, jadi alat bantu (tooling) dan pola komunitas sedang berkembang. Nantikan pembaruan dukungan IDE yang menampilkan sintaks baru ini dalam autocomplete dan saran quick-fix. Perhatikan para pemelihara pustaka: banyak yang akan mulai bermigrasi dari generik publik ke parameter const, yang mungkin memperkenalkan perubahan yang merusak (breaking changes) bagi kode yang sebelumnya mengandalkan cast as const secara eksplisit.

Kesimpulan: Dengan menanamkan pelestarian literal secara langsung ke dalam parameter tipe fungsi, const type parameter TypeScript menghilangkan sumber umum kesalahan widening dan mengalihkan keamanan dari pemanggil kembali ke perancang API. Gunakanlah untuk setiap titik masuk (entry point) generik yang Anda miliki; simpan as const untuk nilai lokal atau API eksternal.