Challenge 2: Augment Express's Request — Possible Solution ==================================================================== // types/express/index.d.ts import "express"; declare module "express" { interface Request { requestId: string; } } // request-id-middleware.ts import { randomUUID } from "crypto"; import type { Request, Response, NextFunction } from "express"; function requestIdMiddleware(req: Request, res: Response, next: NextFunction): void { req.requestId = randomUUID(); next(); } // server.ts import express from "express"; const app = express(); app.use(requestIdMiddleware); app.get("/orders", (req, res) => { // req.requestId is typed as `string` here, no cast or `as any` needed — // the augmentation applies everywhere Express's Request type is used. console.log(`[${req.requestId}] handling /orders`); res.json({ requestId: req.requestId, orders: [] }); }); WHY THIS WORKS -------------- - `import "express";` at the top of the augmentation file is required — without any import or export statement, TypeScript would treat the file as a global script rather than a module, and `declare module "express"` would not merge correctly into the library's own module. - Because `declare module "express" { interface Request { ... } }` merges with Express's own `Request` interface declaration (the same mechanic from Challenge 1, just applied across package boundaries), every file that imports `Request` from "express" sees the augmented shape — there's no need to import a special extended type in route handlers. - Using `requestId: string` (not `requestId?: string`) reflects that the middleware unconditionally sets it before any route handler runs — if a request could reach a handler without the middleware having run, the field should be optional (`requestId?: string`) instead, to avoid lying to the type system about a guarantee that doesn't actually always hold.