首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >属性'serializeUser‘在类型’UserModel‘..ts中不存在(2339)

属性'serializeUser‘在类型’UserModel‘..ts中不存在(2339)
EN

Stack Overflow用户
提问于 2022-04-20 04:18:44
回答 1查看 881关注 0票数 0

这是我的models/users.ts文件:

代码语言:javascript
复制
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
import passportLocalMongoose from 'passport-local-mongoose';

export interface digitalWalletDocument extends mongoose.Document{
    currencyName: string;
    value: number;

}

const digitalWalletSchema = new Schema<digitalWalletDocument>({
    currencyName : {
        type : String
    },
    value : {
        type : Number
    }
});


export interface UserDocument extends mongoose.Document{
    username :  String;
    firstName : String;
    lastName : String;
    email : String;
    telNumber : Number;
    nationalCode : Number;
    admin : Boolean;
    image :  String;
    wallet : Number;
    rate : Number;
    shabaCode :Number;
    cardNumber : Number;
    birthDay : String;
    status : String;
    address : String;
    documnetPath : String;
    description : String;
    purchased : String;
    digitalWallet : digitalWalletDocument;
}

export const userSchema = new Schema<UserDocument>({
    username : {
        type : String,
        sparse : true ,
        unique : true
    },
    firstName : {
        type: String
    },
    lastName : {
        type : String
    },
    email : {
        type : String,
        unique : true
    },
    telNumber : {
        type : Number
    },
    nationalCode : {
        type : Number,
        sparse : true,
        unique : true
    },
    admin : {
        type:Boolean,
        default : false
    },
    image : {
        type : String
    },
    wallet: {
        type : Number,
        default : 0
    },
    rate : {
        type : Number,
        default : 0
    },
    shabaCode : {
        type : Number
    },
    cardNumber : {
        type : Number
    },
    birthDay : {
        type : String
    },
    status : {
        type : String
    },
    address : {
        type : String
    },
    documnetPath : {
        type : String
    },
    description : {
        type: String
    },
    purchased : [String],
    digitalWallet : [digitalWalletSchema]
}, {timestamps : true});

export interface UserModel extends mongoose.Model<UserDocument> {};

userSchema.plugin(passportLocalMongoose,{usernameField : 'email'});

export default mongoose.model<UserDocument,UserModel>('User' , userSchema);

下面是使用authentication.ts文件的user.ts文件:

代码语言:javascript
复制
import express, {Request, Response, NextFunction} from 'express';
import mongoose from 'mongoose';
import passport from 'passport';
import passportLocal from 'passport-local';
const LocalStrategy = passportLocal.Strategy;
import passportJWT from 'passport-jwt';
const passportJWTStrategy = passportJWT.Strategy;
const ExtractJWT = passportJWT.ExtractJwt;
import JWT from 'jsonwebtoken';
import User from './models/users';
import config from './config';

export const local = passport.use(new LocalStrategy( User.authenticate()));

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
    
exports.getToken = (user: any) => {
    return JWT.sign(user, config.secretKey,{ expiresIn : "2d"});
};

const opt = {
    secretOrKey : config.secretKey,
    jwtFromRequest : ExtractJWT.fromAuthHeaderAsBearerToken()
};


export const jwtAuth = passport.use(new passportJWTStrategy(opt , (payload ,done) => {

    User.findOne({_id : payload._id},(err: any , user: typeof User ) => {
        if(err){
            return done(err,false);
        }
        else if(user){
            return done(null , user);
        }
        else{
            return done(null, false);
        }
    });
}));

export const verifyUser = passport.authenticate('jwt', {session : false});

export function verifyAdmin(req: Request, res: Response, next: NextFunction) {
    if(req.user.admin){
        return next();
    }
    else{
        let err = new Error('Only Admin can access to this web page or resources!');
        err.status = 403;
        return next(err);
    }
}

我收到以下错误消息:

代码语言:javascript
复制
Property 'authenticate' does not exist on type 'UserModel'.ts(2339)
Property 'serializeUser' does not exist on type 'UserModel'.ts(2339)
Property 'deserializeUser' does not exist on type 'UserModel'.ts(2339)

造成错误的原因是以下几行:

代码语言:javascript
复制
export const local = passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

我不知道是什么问题,我如何解决它?我试着在网上搜索,找到类似的问题,做类似问题的答案,但没有一个对我有用!

EDIT:我修改了代码,就像@Linda在她的回答中建议的那样。但出现了以下新错误:

没有过载和这个电话匹配。重载2中的1,'(fn:(user: User,done:(err: any,id?:any) => void) => void):=>‘,给出了以下错误。类型'(user: UserDocument,cb:(err: any,id?:any) => void) => void‘的参数“(User: User,done:(err: any,id?:any) => void) => =>’。参数'user‘和'user’的类型是不兼容的。类型‘UserDocument’中缺少以下属性:用户名、firstName、lastName、电子邮件和66更多。 重载2中的2,'(fn:(req: IncomingMessage,user: User,done:(err: any,id?:=> void) => void)=> void):=>‘,给出了以下错误。

错误发生在代码的这一行:

代码语言:javascript
复制
passport.serializeUser(User.serializeUser());

authentication.ts文件上。

当我删除User.serializeUser()前面的括号时,错误会消失,但我不确定是否是这样。

EN

回答 1

Stack Overflow用户

发布于 2022-04-30 16:59:06

问题

给出错误的字段是由passport-local-mongoose包添加的字段。

当你打电话:

代码语言:javascript
复制
userSchema.plugin(passportLocalMongoose, {usernameField : 'email'});

您正在将这些附加字段(如authenticate()serializeUser() )添加到模型中。

不幸的是,用于类型声明的猫鼬Schema.plugin()表示,它返回与其启动时相同的对象类型:

代码语言:javascript
复制
/** Registers a plugin for this schema. */
plugin(fn: (schema: Schema<DocType>, opts?: any) => void, opts?: any): this;

因此,您的代码无法自动检测这些添加的属性。

解决方案

步骤1:

安装@types/passport-local-mongoose以加载passport-local-mongoose包的类型声明。

代码语言:javascript
复制
npm i --save-dev @types/passport-local-mongoose

附加类型被添加到mongoose命名空间中,因此您可以使用mongoose.TypeName访问它们,就像访问标准猫鼬类型一样。

第2步:

声明您的UserModel接口是PassportLocalModel而不是普通的Model

代码语言:javascript
复制
export interface UserModel extends mongoose.PassportLocalModel<UserDocument> {};

您需要保留已经在这里调用mongoose.model()的泛型类型参数:

代码语言:javascript
复制
export default mongoose.model<UserDocument, UserModel>('User' , userSchema);

但是现在您的User模型将具有方法 of a PassportLocalModel

另外,您希望在您的string接口中使用小写的TypeScript和number

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71934042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档