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
His one segment andRis everything after it.Split<'plain'>→["plain"]
Each resolved type above was printed by TypeScript 6.0.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.

