Skip to content
webtype.orgwebtype.org

    ↑↓ move · ⏎ open · esc close

    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 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.