Challenge 1: Add .post() With a Typed Body — Possible Solution ==================================================================== type ExtractParams = Path extends `${string}:${infer Param}/${infer Rest}` ? { [K in Param | keyof ExtractParams]: string } : Path extends `${string}:${infer Param}` ? { [K in Param]: string } : {}; type Handler = (req: { params: ExtractParams }) => void; type PostHandler = (req: { params: ExtractParams; body: Body }) => void; type Routes = Record void>; class Router { private routes: R; constructor(routes: R) { this.routes = routes; } get( path: Path, handler: Handler ): Router>> { return new Router({ ...this.routes, [path]: handler } as R & Record>); } post( path: Path, handler: PostHandler ): Router>> { return new Router({ ...this.routes, [path]: handler } as R & Record>); } } // --- Usage --- interface CreateUserBody { name: string; email: string; } const router = new Router({}) .get("/users/:id", (req) => { console.log(`Fetching user ${req.params.id}`); // params.id: string }) .post<"/users", CreateUserBody>("/users", (req) => { console.log(`Creating ${req.body.name} <${req.body.email}>`); // body typed as CreateUserBody // req.params is {} here since "/users" has no :params }); WHY THIS WORKS -------------- - PostHandler adds a second generic dimension (Body) alongside the existing Path-derived ExtractParams — the handler's req object now carries both a path-derived shape and an independently-specified one. - Body isn't inferable from Path the way params are (there's nothing in the path string that describes a request body), so it's supplied explicitly as a type argument at the call site (`.post<"/users", CreateUserBody>(...)`) — a common, honest trade-off when a value genuinely can't be derived from something else already in scope. - The Router class itself needed no structural changes to accommodate a second route-registration method — `.post()` follows the exact same accumulator shape as `.get()` (merge one more entry into R via intersection), demonstrating that the pattern from the chapter generalizes to more than one kind of route.