type Size = "sm" | "md" | "lg";
type Color = "red" | "blue";
type ClassName = `${Color}-${Size}`; // "red-sm" | "red-md" | ... 6 members
type EventName = "click" | "focus";
type Handler = `on${Capitalize<EventName>}`; // "onClick" | "onFocus"
type CssLength = `${number}px`;
const w: CssLength = "12px"; // ok
const h: CssLength = "12"; // error
Template literal types build string literal types with the same syntax as JavaScript template strings, but at the type level. For example, ${Color}-${Size} builds class names like "red-sm".
When a placeholder holds a union, the result is every combination. So two colors and three sizes give six class names.
They work with four built-in helpers that change text:
UppercaseLowercaseCapitalizeUncapitalize
This is how you build names like onClick from click.
A placeholder can also be string or number. This creates a pattern instead of a fixed list. For example, ${number}px means any string with a number followed by px.
Common uses:
- typed event names
- CSS values
- route patterns
- renaming keys in mapped types
- Template literal types build string literal types with template string syntax.
- A union in a placeholder expands to every combination.
Capitalize,Uppercase,LowercaseandUncapitalizechange the text.- A
stringornumberplaceholder describes a pattern, like${number}px. - They are often used with key remapping in mapped types.
Read more