TypeScript Academy · Lesson

A Mini Type-Level Route Parser

Parse route paths into typed parameter objects.

Lesson 4 of 413 steps

A Mini Type-Level Route Parser is a free TypeScript Academy lesson on CoddyKit. This is lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, and your progress syncs across the web and the CoddyKit app. The TypeScript Academy course includes 4 lessons in total.

The Goal

We build a route parser that reads a path like "users/:id/posts/:postId" and produces a typed params object { id: string; postId: string }, entirely at compile time. This is a real pattern used by typed routers.

type Params = ParseRoute<"users/:id/posts/:postId">;
// Goal: { id: string; postId: string }

Recognizing a Parameter

A path segment is a parameter when it starts with ":". We match that prefix with a template literal and infer the parameter name after the colon.

Notation: real TypeScript writes template literal types with backtick-delimited strings containing dollar-brace holes. In these snippets we show that pattern as Tpl<...>, listing each part in order; e.g. a backtick template matching the literal prefix then Rest appears as Tpl<'prefix', infer Rest>.

type ParamName<S> = S extends Tpl<':', infer Name> ? Name : never;
// Tpl<...> denotes a backtick template literal type: a colon then Name

type X = ParamName<':id'>;   // 'id'
type Y = ParamName<'users'>; // never

Splitting the Path

First split the route into segments on "/", reusing the Split type. Each segment is then either a literal or a parameter.

type Split<S extends string, Sep extends string> =
  S extends Tpl<infer H, Sep, infer T> ? [H, ...Split<T, Sep>] : [S];
// Tpl<H, Sep, T> = a template literal type matching H, then Sep, then T

type Segs = Split<'users/:id', '/'>; // ['users', ':id']

Direct Template Recursion

We can also parse the raw string without splitting first, by matching one segment at a time. Match up to the next "/", handle that segment, then recurse on the rest.

type ParseRoute<S extends string> =
  S extends Tpl<infer Seg, '/', infer Rest>
    ? SegParam<Seg> & ParseRoute<Rest>
    : SegParam<S>;
// Tpl<Seg, '/', Rest> matches a segment, a slash, then the rest

Per-Segment Parameter

The helper turns a single segment into either a one-property object (if it is a parameter) or an empty object (if it is a literal).

type SegParam<S extends string> =
  S extends Tpl<':', infer Name> ? { [K in Name]: string } : {};
// Tpl<':', Name> matches a colon followed by the param name

type X = SegParam<':id'>;   // { id: string }
type Y = SegParam<'posts'>; // {}

Combining With Intersection

Each segment contributes its params via intersection. Empty objects vanish in an intersection, so only real parameters remain in the final type.

type Params = ParseRoute<"users/:id/posts/:postId">;
// { id: string } & {} & { postId: string } & {}
// = { id: string; postId: string }

Tracing the Parse

For "users/:id/posts/:postId":

  • Seg "users" -> {} , recurse on ":id/posts/:postId"
  • Seg ":id" -> { id: string }, recurse on "posts/:postId"
  • Seg "posts" -> {}, recurse on ":postId"
  • Seg ":postId" -> { postId: string }, base case
type Final = { id: string } & { postId: string };

Cleaning the Result

The intersection of objects displays awkwardly. A "prettify" helper flattens it into a single clean object type using a mapped type over its keys.

type Prettify<T> = { [K in keyof T]: T[K] } & {};

type Clean = Prettify<ParseRoute<"users/:id">>; // { id: string }

Using the Parser

Plug the parsed type into a function so the handler receives correctly typed params. Passing the wrong key becomes a compile error.

declare function route<P extends string>(
  path: P,
  handler: (params: Prettify<ParseRoute<P>>) => void
): void;

route("users/:id", p => { const id: string = p.id; });

Typed Params Payoff

The compiler now derives params from the route string itself. Rename a parameter in the path and every handler updates its expected keys automatically. No manual interface, no drift between route and handler.

route("users/:userId", p => {
  const u = p.userId; // ok
  // const x = p.id; // error: id does not exist
});

Extending the Parser

This mini parser is the seed of a full typed router. You can add typed values (number params), wildcards, and optional segments, all by enriching the per-segment helper with more template patterns. The recursive-template structure stays the same.

type SegParam2<S extends string> =
  S extends Tpl<':', infer N, '(number)'> ? { [K in N]: number }
  : S extends Tpl<':', infer N> ? { [K in N]: string }
  : {};
// Tpl<...> stands for a backtick template literal type pattern

Quick Check

Test your understanding of the route parser.

Recap

You built a compile-time route parser.

  • Match each segment with recursive template literal inference.
  • Parameter segments (:name) become { name: string }.
  • Literal segments become {} and vanish in the intersection.
  • Prettify flattens the result into clean params.

Course 25 next: end-to-end type safety with tRPC.

Free to start

Learn TypeScript with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
101
Lessons
352

Frequently Asked Questions

Is the “A Mini Type-Level Route Parser” lesson free?

Yes — the full text of “A Mini Type-Level Route Parser” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO. The TypeScript Academy course includes 4 lessons in total.

What will I learn in “A Mini Type-Level Route Parser”?

Parse route paths into typed parameter objects. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start TypeScript Academy?

No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “A Mini Type-Level Route Parser” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this TypeScript Academy lesson?

Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Parser Combinator Concepts
  2. Type-Level String Splitting
  3. Parsing with Template Literals
  4. A Mini Type-Level Route Parser
← Back to TypeScript Academy