简体   繁体   中英

Property 'id' does not exist on type 'User' with Passport and Typescript

Using PassportJS in Express with Typescript, I get the following error when trying to access req.user.id .

Property 'id' does not exist on type 'User'.ts(2339)

When logging just req.user to the console, I can clearly see that there is an id property, however Typescript is throwing this error none the less.

Here is a snippet of the code I'm trying to run,

userRouter.post("/session", async (req: Request, res: Response) => {
  const { startTime, endTime, desc } = req.body;
  const { user } = req;

  console.log(user!.id);

  res.json({ message: "CREATE NEW SESSION" });
});

As I am new with TS, I am unsure of the steps to take in resolving this problem. My guess is I have to change an interface or something in the configuration somewhere.

PassportJS does not declare any properties of the User interface . You can extend this definition by merging it with the following in your code:

declare global {
  namespace Express {
    interface User {
      id: string
    }
  }
}

and your code should compile.

But where do you expect the user.id to be filled? Have you written your own code for that? Or does PassportJS fill this property although it does not declare it?

(Strangely, I was able to "fool" the Typescript compiler by replacing user..id with user["id"] .)

I came across the same error and I solved it as below:

I made IUser interface:

 import type { Document } from "mongoose"; interface IUser extends Document { name: string; email: string; hash: string; salt: string; isAdmin: boolean; } export default IUser;

And I use it in user model:

 import { Schema, model } from "mongoose"; import IUser from "../types/User"; const userSchema = new Schema<IUser>( { name: { type: String, required: true, }, email: { type: String, required: true, unique: true, }, hash: { type: String, required: true, }, salt: { type: String, required: true, }, isAdmin: { type: Boolean, required: true, default: false, }, }, { timestamps: true, } ); const User = model("User", userSchema); export default User;

And in the user controller I used it like so:

 import type { Request, Response } from "express"; import { genPassword } from "../utils/passwordUtils"; import User from "../models/userModel"; import IUser from "../types/User"; export const getUserProfile = async (req: Request, res: Response) => { const currentUser = req.user as IUser; try { const user = await User.findById(currentUser._id); if (user) { res.json({ success: true, user }); } else { res.status(404); throw new Error("User not found"); } } catch (error) { res.status(404); throw new Error("User not found"); } }; export const updateUserProfile = async (req: Request, res: Response) => { const currentUser = req.user as IUser; const user = await User.findById(currentUser._id); if (user) { user.name = req.body.name || user.name; user.email = req.body.email || user.email; if (req.body.password) { const saltHash = genPassword(req.body.password); const salt = saltHash.salt; const hash = saltHash.hash; user.hash = hash; user.salt = salt; } const updatedUser = await user.save(); res.json({ success: true, user: updatedUser }); } else { res.status(404); throw new Error("User not found"); } };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM