- Published on
TypeScript Trick #2: Template Literal Types
Template Literal Types landed in TS 4.1 and quickly became a game-changer. They let you create dynamic, precise string types—so you get both type-safety and autocomplete for values that follow a pattern.
1. How Do They Work?
type Lang = "en" | "pl";
type Page = "home" | "about";
type Route = `/${Lang}/${Page}`;
// "/en/home" | "/en/about" | "/pl/home" | "/pl/about"
2. Real-life Example: API Paths
type Method = "GET" | "POST";
type Endpoint = "users" | "posts";
type ApiPath = `/api/${Method}/${Endpoint}`;
// Type: "/api/GET/users" | "/api/GET/posts" | ...
3. Extracting Strings With Types
type ExtractDomain<T extends string> =
T extends `https://${infer D}/${string}` ? D : never;
type D = ExtractDomain<"https://mordo.dev/page">; // "mordo.dev"
With infer
, you can grab domains or parts of strings at the type level—super useful for router definitions and type-safe utilities.
4. CSS, Keys, Plurals, and More
CSS units:
type Unit = "px" | "%";
type CssValue = `${number}${Unit}`; // e.g. "10px"
- No more copy-paste enums or unions!
- Handy for pluralization functions, auto-generated error messages, or event names—whatever you can dream up.
5. Watch Out for Performance
Heads up: large unions (like Color × Size × Variant) can explode into a massive number of types. TS recommends caution when generating huge sets of combinations.
✅ TL;DR
🍻 Template Literal Types = dynamic, type-safe, IDE-friendly string types.
Great for: API paths, CSS, event handlers, validations, enums, and much more.
Don't overdo it—huge unions can slow down TS and your IDE.
Final Thought
Template literal types are one of those features that give you massive power for almost no effort. In the next parts of this series, I'll break down each trick with real-world code you can use in your own repo.
Let me know which topics you're most interested in—let's make TypeScript even more fun in 2025!