Template literal type membangun string literal type dengan sintaks backtick yang sama seperti template string JavaScript. `on${Capitalize<"click" | "focus">}` adalah tipe "onClick" | "onFocus", yang dihitung oleh compiler:
Template literal type hanya ada saat kompilasi. Tipe ini mengecek string literal dan nilai bertipe selama kamu menulis kode; ia tidak menambahkan apa pun ke output JavaScript. Tabel handler di atas memakai Record untuk mewajibkan satu fungsi untuk setiap nama.
Sintaks
Di dalam backtick, kamu menulis teks literal dan placeholder ${...}. Placeholder berisi tipe, bukan nilai: literal type string, number, bigint atau boolean, union dari tipe-tipe itu, atau salah satu tipe lebar string, number, bigint, boolean, null dan undefined.
Placeholder dengan tipe lebar seperti string atau number membentuk pola: tipenya tetap `hello ${string}` dan string apa pun yang cocok akan diterima. Placeholder dengan union yang terbatas, seperti boolean, dijabarkan menjadi anggota-anggotanya.
Union Berlipat Ganda
Dengan beberapa union, hasilnya adalah setiap kombinasinya:
Tiga ukuran dikali dua warna menghasilkan enam anggota. Jumlahnya cepat membesar: lima placeholder yang masing-masing berisi union sepuluh huruf akan menjadi 100.000 anggota, dan TypeScript menolaknya dengan error TS2590: Expression produces a union type that is too complex to represent. Pakai placeholder lebar seperti ${string} kalau kamu tidak butuh setiap nilai yang persis.
Uppercase, Lowercase, Capitalize, Uncapitalize
Empat tipe bawaan mengubah huruf besar kecil pada string literal type. Keempatnya intrinsik: diimplementasikan di dalam compiler, bukan ditulis dalam TypeScript.
| Tipe | Input | Hasil |
|---|---|---|
Uppercase<S> | "hello world" | "HELLO WORLD" |
Lowercase<S> | "Content-Type" | "content-type" |
Capitalize<S> | "hello world" | "Hello world" |
Uncapitalize<S> | "UserName" | "userName" |
Tipe-tipe ini hanya mengubah tipe. Untuk membangun string runtime yang sesuai, kamu tetap memanggil toUpperCase() atau memotong string dan mengubah huruf pertamanya sendiri, lalu memberi tahu TypeScript bahwa hasilnya punya tipe yang persis:
as diperlukan karena toUpperCase() diberi tipe yang mengembalikan string biasa. Signature fungsinya itulah yang dilihat pemanggil, jadi capitalize("report") punya literal type "Report".
Pola String: ${number}px dan Sejenisnya
Tipe pola menerima setiap string dengan bentuk tertentu. Ini praktis untuk nilai CSS, id, dan key dengan prefix yang sudah diketahui:
${number} menerima string apa pun yang dibaca JavaScript sebagai angka, dan itu lebih longgar daripada kelihatannya: "-3px", "1e3px" dan "0x10px" semuanya lolos pengecekan tipe. Anggap pola ini sebagai penjaga terhadap salah ketik di literal, bukan validasi yang lengkap.
Template Literal dengan Mapped Type
Template literal type paling berguna sebagai klausa as di mapped type, tempat ia membuat nama property dari nama property lain:
string & K hanya mempertahankan key string, karena Capitalize tidak menerima number atau symbol. Setiap callback mendapat tipe parameternya dari property yang diawasinya.
Mem-parse String dengan infer
Di conditional type, template literal bisa mencocokkan sebuah string dan menangkap bagian-bagiannya dengan infer. Contoh ini mengambil nama-nama parameter dari pola route:
Hilangkan postId di pemanggilan, dan compiler melaporkannya sebagai yang hilang.
Ekspresi Template Dilebarkan Menjadi string
Ekspresi template string di kode biasa bertipe string, walaupun setiap bagiannya adalah literal type. Tambahkan as const untuk mempertahankan template literal type-nya:
Tanpa as const, meng-assign loose ke `log:${Level}` gagal, karena string bisa berupa apa saja.
Pertanyaan yang sering diajukan
Apa itu template literal type di TypeScript?
String literal type yang ditulis dengan backtick dan placeholder ${...}, seperti template string JavaScript tetapi di level tipe. type Greeting = `hello ${string}` menerima string apa pun yang diawali hello , dan `on${Capitalize<"click">}` adalah literal type "onClick".
Apa yang terjadi kalau union ditaruh di dalam template literal type?
Template-nya dijabarkan untuk setiap anggota, dan dengan beberapa union kamu mendapat setiap kombinasinya. `${"sm" | "lg"}-${"red" | "blue"}` adalah "sm-red" | "sm-blue" | "lg-red" | "lg-blue". Kombinasi yang sangat besar gagal dengan error TS2590.
Apa fungsi Uppercase, Lowercase, Capitalize dan Uncapitalize?
Keempatnya adalah tipe bawaan yang mengubah string literal type: Uppercase<"id"> adalah "ID", Lowercase<"ID"> adalah "id", Capitalize<"name"> adalah "Name" dan Uncapitalize<"Name"> adalah "name". Tipe-tipe ini hanya mengubah tipe; untuk mengubah string saat runtime kamu tetap memanggil toUpperCase() dan sejenisnya.
Apakah template literal type memvalidasi string saat runtime?
Tidak. Seperti setiap tipe TypeScript, tipe ini dihapus saat kompilasi, jadi ia hanya mengecek string literal dan nilai bertipe saat kompilasi. String yang datang saat runtime, dari JSON atau input pengguna, hanyalah string sampai kamu mengeceknya dengan kodemu sendiri.
Kenapa template string saya bertipe string, bukan literal type?
Ekspresi template seperti `on${event}` dilebarkan menjadi string saat di-assign ke variabel. Tambahkan as const (`on${event}` as const) atau beri anotasi tipe target, dan TypeScript mempertahankan template literal type-nya, misalnya "onclick" | "onfocus".