A Mini Type-Level Route Parser
Parse route paths into typed parameter objects.
A Mini Type-Level Route Parser is a free TypeScript Academy lesson on CoddyKit — 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, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
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'>; // neverSplitting 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 restPer-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 patternQuick 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. Prettifyflattens the result into clean params.
Course 25 next: end-to-end type safety with tRPC.
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, and the TypeScript Academy course includes 4 lessons in total. 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.
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; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
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
- Parser Combinator Concepts
- Type-Level String Splitting
- Parsing with Template Literals
- A Mini Type-Level Route Parser