Typed Request Handlers & Middleware
Express's own types describe the shape of a request/response, but leave req.body, req.params, and req.query as loosely typed by default. This lesson tightens that up and builds a reusable pattern for async route handlers.
Typing params, body, and query explicitly
Request's first generic parameter types req.params. Left as plain Request, req.params.id would be typed loosely, spelling it out here catches a typo like req.params.taskId at compile time instead of at 2am in production logs.
A reusable async handler wrapper
Express doesn't automatically catch a rejected Promise from an async route handler, an unhandled rejection just hangs or crashes the process.
asyncHandler wraps any async function, catches whatever it throws or rejects with, and forwards it to next(err), Express's normal error-handling path, instead of letting it disappear silently.
Typed error-handling middleware
Express recognizes error-handling middleware by its four parameters, err first, note it's typed unknown, not Error, anything can technically be thrown in JavaScript, so instanceof Error narrowing is what makes reading .message safe.
TIP
Register app.use(errorHandler) after every route. Express matches error middleware in registration order too, one placed too early simply never gets reached.