I am creating a MERN Stack web project using typescript.
Below is authRoutes.ts
import { Router } from "express";
import { register, login } from "./../controllers/authController";
const router = Router();
// Register route
router.post("/register", register);
// Login route
router.post("/login", login);
export default router;
And here is authController.ts
import { NextFunction, Request, Response } from "express";
import User from "../models/userModel"; // Import the User model
// Register a new user
export const register = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response> => {
try {
const { name, email, password, isAdmin } = req.body;
// Check if the user already exists
const userExists = await User.findOne({ email });
if (userExists) {
return res.status(400).json({ message: "User already exists" });
}
// Create a new user and save to the database
const user = new User({ name, email, password, isAdmin });
await user.save();
return res.status(201).json({ message: "User created successfully" });
} catch (err) {
console.error(err);
return res.status(500).json({ message: "Server error" });
}
};
// Login user
export const login = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response> => {
try {
const { email, password } = req.body;
// Find user by email
const user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ message: "Invalid credentials" });
}
// Simple password check (no bcrypt for now)
if (user.password !== password) {
return res.status(400).json({ message: "Invalid credentials" });
}
return res.status(200).json({ message: "Login successful" });
} catch (err) {
console.error(err);
return res.status(500).json({ message: "Server error" });
}
};
The authRoutes.ts is giving the below error at line 7 and 10.
No overload matches this call. The last overload gave the following error. Argument of type '(req: Request, res: Response, next: NextFunction) => Promise' is not assignable to parameter of type 'Application<Record<string, any>>'. Type '(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<...>' is missing the following properties from type 'Application<Record<string, any>>': init, defaultConfiguration, engine, set, and 63 more.ts(2769) index.d.ts(168, 5): The last overload is declared here.
This is a leaning project so i dont have a very good grasp on things here. Nothing i try seem to work here.
You're getting this error because the function type passed to a route must be of type RequestHandler
, and also, this type of declaring controllers is not recommended when using Typescript in Express.
Below is the correct code which solves all the errors and proper format of declaring and using controller functions -
import { NextFunction, Request, RequestHandler, Response } from "express";
import User from "./userModel"; // Import the User model
class UserController {
public register: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {
try {
const { name, email, password, isAdmin } = req.body;
const userExists = await User.findOne({ email });
if (userExists) {
res.status(400).json({ message: "User already exists" });
return;
}
const user = new User({ name, email, password, isAdmin });
await user.save();
res.status(201).json({ message: "User created successfully" });
} catch (err) {
console.error(err);
next(err);
}
};
public login: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {
try {
const { email, password } = req.body;
// Find user by email
const user = await User.findOne({ email });
if (!user) {
res.status(400).json({ message: "Invalid credentials" });
return;
}
// Simple password check (no bcrypt for now)
if (user.password !== password) {
res.status(400).json({ message: "Invalid credentials" });
return;
}
res.status(200).json({ message: "Login successful" });
} catch (err) {
console.error(err);
next(err);
}
};
}
export const userController = new UserController();
and use the above in the following manner -
import { Router } from "express";
import { userController } from "./authController";
const router = Router();
// Register route
router.post("/register", userController.register);
// Login route
router.post("/login", userController.login);
export default router;
(Make appropriate changes in the import paths and use)