typescriptexpressauthenticationmiddlewarenext.js14

Typescript No overload matches this call


I'm new to TypeScript and I'm currently stuck. I have a next.js and express app.

I'm getting the following error: No overload matches this call.

No overload matches this call.
  The last overload gave the following error.
    Argument of type '(req: Request, res: Response, next: NextFunction) => Promise<Response<any, Record<string, any>> | undefined>' is not assignable to parameter of type 'RequestHandlerParams<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
      Type '(req: Request, res: Response, next: NextFunction) => Promise<Response<any, Record<string, any>> | undefined>' is not assignable to type 'RequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
        Type 'Promise<Response<any, Record<string, any>> | undefined>' is not assignable to type 'void | Promise<void>'.
          Type 'Promise<Response<any, Record<string, any>> | undefined>' is not assignable to type 'Promise<void>'.
            Type 'Response<any, Record<string, any>> | undefined' is not assignable to type 'void'.
              Type 'Response<any, Record<string, any>>' is not assignable to type 'void'.ts(2769)
index.d.ts(203, 5): The last overload is declared here.

my route file is

import { isAuthenticated } from "../middlewares/isAuthenticated";
const router = express.Router();
router.route("/check-auth").get(isAuthenticated, checkAuth);
export default router;

middleware file is

import { NextFunction, Request, Response } from "express";

declare global {
    namespace Express{
        interface Request {
            id: string;
        }
    }
}

export const isAuthenticated = async (req: Request, res: Response, next: NextFunction) => 
    {
    try {
        const token = req.cookies.token;
        if (!token) {
            return res.status(401).json({
                success: false,
                message: "User not authenticated"
            });
        }
      
        req.id = decode.userId;
        next();
    } catch (error) {
        return res.status(500).json({
            message: "Internal server error"
        })
    }
}

Solution

  • The TypeScript error is occurring because Express expects middleware functions to return void or Promise<void>.

    By making your function async, it automatically returns a Promise, and because you’re returning res.status(...).json(...) (which is of type Response), the function’s return type doesn’t align with Express’s expected Promise<void>.

    In Express, middleware functions should either call next() or end the response without returning any value. Either remove async or make sure all paths return Promise

    Updated isAuthenticated.ts

    export const isAuthenticated = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
        try {
            const token = req.cookies?.token;
            if (!token) {
                res.status(401).json({ success: false, message: "User not authenticated" });
                return; // Exit without returning a Response
            }
            req.id = "exampleUserId"; // Assume this ID is decoded from token
            next();
        } catch (error) {
            res.status(500).json({ message: "Internal server error" });
        }
    };