Constructs
Template literal types
String interpolation at the type level — and, read backwards, pattern matching on strings.
What it is
Building strings is the obvious half. The half that matters is that the same syntax works in an `extends` clause with `infer`, which turns a template into a parser: `S extends \`${infer Head}.${infer Rest}\`` splits on the first dot. Every path type, every route type and every case converter in the archive is that one idea repeated.
Examples
Handler<AppEvent>
→"onClick" | "onFocus"Split<'a.b'>→["a", "b"]Matching from the left, shortest first — so `H` is one segment and `R` is everything after it.
Split<'plain'>→["plain"]
Each resolved type above was printed by TypeScript 5.9.3, not written by hand.
What it does not do
- It cannot match greedily or backwards. Inference always takes the shortest match from the left, so splitting on the *last* separator needs recursion rather than a cleverer pattern.
- It does not stay finite for free. Interpolating two unions multiplies them, and a few unions of a few members each will exceed the compiler’s limit on union size.
Takeaway
A template in a type position builds; the same template in an `extends` clause takes apart. Learning to read them in the second direction is the unlock.