Search code examples
node.jstypescriptexpress

Return type for Express routes with TypeScript


I'm trying to use TypeScript to it's full potential, so I avoid any if possible.

I've seen Express routes defined like this:

import { Request, Response } from "express";

myRouter.route("/foo").post((req: Request, res: Response): Response => {
  return res.send("Hello World");
});

That works because send() returns an express Response.

But if I do a redirect:

myRouter.route("/bar").post((req: Request, res: Response): Response => {
  return res.redirect("/baz");         // redirect() returns void!
});

That won't compile because redirect() returns void, not Response.

Options:

  • The easy fix is to make the route return any, but I want to avoid that if possible
  • I've seen code that does as unknown as Response but that seems like a hack

What is the correct way to declare routes' return types, without using any?


Solution

  • The accepted answer is outdated.

    The problem is that the expected usage based on the current Express typings is different. The expected return types for route handlers and middlewares is void and Promise<void>, any other return is not expected.

    It should be:

      res.send("Hello World");
    

    And in case of an early return:

      res.send("Hello World");
      return;
    

    The support for Promise<void> type was added in Express 4 at some point to make it compatible with async functions, and Express 5 supports rejected promises for error handling.

    There is no necessity to specify parameter types when a function is not declared separately, they are inferred. The use of satisfies type constraint can improve the output of TypeScript errors:

    router.post((req, res) => {
      res.send("Hello World");
    } satisfies RequestHandler);
    

    When a function is declared separately:

    const routeHandler: RequestHandler = (req, res, next) => {
      res.send("Hello World");
    };
    

    And a longer way:

    const routeHandler = (req: Request, res: Response, next: NextFunction): void => {
      res.send("Hello World");
    } satisfies RequestHandler;