Steve Kinney

Full-Stack TypeScript

Type-Safe Route Registration

One limitation of Express is that route paths are just strings, not checked against parameter types. We can build a type-safe router:

function route<
  P extends Record<string, string> = {},
  ResBody = any,
  ReqBody = any,
  ReqQuery = qs.ParsedQs,
>(path: string, …handlers: Array<RequestHandler<P, ResBody, ReqBody, ReqQuery>>) {
  return { path, handlers };
}
const userRoutes = [
	route<{ id: string }, UserResponse>('/users/:id', (req, res) => {
		const userId = req.params.id;
		// …
	}),
	route<{}, UserResponse[], {}, { query?: string }>('/users', (req, res) => {
		const searchQuery = req.query.query;
		// …
	}),
];
userRoutes.forEach(({ path, handlers }) => {
  app.get(path, …handlers);
});

While this doesn’t validate that :id in the path corresponds to the id in your params type, it does ensure that handlers receive correctly typed requests.

Last modified on .