๐ง๐๐ฝ๐ฒ๐ฆ๐ฐ๐ฟ๐ถ๐ฝ๐ ๐ง๐ฒ๐บ๐ฝ๐น๐ฎ๐๐ฒ ๐๐ถ๐๐ฒ๐ฟ๐ฎ๐น ๐ง๐๐ฝ๐ฒ๐
Strings cause many bugs in TypeScript.
You might pass "400px" when a function needs "4rem". You might type "onclick" instead of "onClick". You might build a broken URL because of a trailing slash.
Most developers use runtime validation or hope for the best. You can do better. Template literal types let you enforce string patterns during development.
These types let you compose and constrain strings dynamically. They keep your code safe without adding runtime overhead.
Use them for CSS units:
- type CSSSize =
${number}px|${number}rem|${number}%| "auto";
With this, "16px" works. "16" fails because it misses the unit. "banana" fails because it is not a size.
Use them for event handlers:
- type EventHandler
= on${Capitalize<E>};
If you have an event named "click", TypeScript generates "onClick". If you add a new event to your system, the handler updates automatically.
Use them for API routes:
- type ApiRoute =
/api/${string}|/api/${string}/${string};
This ensures your routes follow a strict structure. You can even use the infer keyword to extract URL parameters from a path string at compile time.
When to avoid them:
- Do not use them for simple unions. If you only have three options, use a standard union.
- Do not create massive unions. Combining many sets of strings can crash the TypeScript compiler.
- Do not use them for runtime validation. These types disappear after you compile. Use Zod or Valibot for user input or API responses.
- Do not try to parse complex languages like SQL or JSON. You will hit recursion limits.
Template literal types turn strings into contracts. They catch mistakes before they reach your users.