如何在Mongoose模型中同时使用分页与静态方法?
解决Mongoose模型同时支持分页与自定义静态方法的TypeScript类型问题
核心问题在于TypeScript类型未合并自定义静态方法与分页插件的静态方法,只需调整模型接口的继承关系即可解决。
修改步骤
- 合并类型接口:让自定义模型接口
IUserModel继承分页插件提供的PaginateModel<IUserDocument>,而非基础的Model<IUserDocument>,这样接口会同时包含自定义静态方法和分页方法的类型定义。 - 更新模型声明:创建模型时使用
IUserModel作为第二个泛型参数,确保TypeScript校验同时覆盖两种方法。
修改后的完整代码
import mongoose, { Schema, Document, Model } from "mongoose"; import bcrypt from "bcrypt"; import mongoosePaginate, { PaginateModel } from 'mongoose-paginate-v2'; interface IUser { username: string; hashedPassword: string; } interface IUserDocument extends IUser, Document { setPassword: (password: string) => Promise<void>; checkPassword: (password: string) => Promise<boolean>; } // 继承PaginateModel,合并自定义静态方法与分页方法类型 interface IUserModel extends PaginateModel<IUserDocument> { findByUsername: (username: string) => Promise<IUserDocument | null>; } const UserSchema: Schema<IUserDocument> = new Schema({ username: { type: String, required: true }, hashedPassword: { type: String, required: true }, }); UserSchema.methods.setPassword = async function (password: string) { const hash = await bcrypt.hash(password, 10); this.hashedPassword = hash; }; UserSchema.methods.checkPassword = async function (password: string) { const result = await bcrypt.compare(password, this.hashedPassword); return result; }; UserSchema.statics.findByUsername = function (username: string) { return this.findOne({ username }); }; UserSchema.plugin(mongoosePaginate); // 使用合并后的IUserModel作为模型类型 const User = mongoose.model<IUserDocument, IUserModel>("User", UserSchema); export default User;
验证用法
现在两种方法都能正常调用且通过TypeScript校验:
// 调用自定义静态方法 const user = await User.findByUsername("testuser"); // 调用分页方法 const paginatedResult = await User.paginate({ username: "testuser" }, { page: 1, limit: 10 });
注:额外修正了
findByUsername的返回值类型,补充了null的可能性,让类型定义更严谨。
内容的提问来源于stack exchange,提问作者Efrain Sanjay Adhikary
相关产品推荐
相关产品推荐

