我正在利用猫鼬类模式。
并为我的 Node 项目使用 TypeScript。
我遵循了猫鼬的打字稿方式...? 以确保我的模型知道我定义的模式,所以我有自动完成等。
但是,使用模式类变得更加棘手。正如他们的文档中所写:
loadClass(( 函数允许您引入方法、静态和 来自 ES6 类的虚拟。类方法映射到架构方法,即 静态方法映射到架构静态,getter/setter 映射到 虚拟的。
所以我的代码看起来像这样:
interface IUser extends mongoose.Document {
firstName: string,
lastName: string
};
const userSchema = new mongoose.Schema({
firstName: {type:String, required: true},
lastName: {type:String, required: true},
});
class UserClass{
static allUsersStartingWithLetter(letter: string){
return this.find({...});
}
fullName(this: IUser){
return `${this.firstName} ${this.lastName}`
}
}
userSchema.loadClass(UserClass);
const User = mongoose.model<IUser>('User', userSchema);
export default User;
我的目标是 TypeScript 能够理解这一点:
-
User
有一个方法allUsersStartingWithLetter
-
User
实例具有方法fullName
在当前配置中,它没有。我自己无法完成。
您是否考虑过将extends mongoose.Model
添加到UserClass
?
class UserClass extends mongoose.Model<IUser> {
static allUsersStartingWithLetter(letter: string){
return this.find({...});
}
fullName(this: IUser){
return `${this.firstName} ${this.lastName}`
}
}
你真的需要使用类吗?您可以使用接口来完成此操作,而无需使用类来执行此操作。下面是一个示例:
/* eslint-disable func-names */
import mongoose from 'mongoose';
export interface Foo {
id?: string;
name: string;
createdAt?: Date;
updatedAt?: Date;
}
export type FooDocument = mongoose.Document & Foo;
const fooSchema = new mongoose.Schema(
{
name: { type: String, required: true },
},
{ timestamps: true }
);
fooSchema.methods.bar = function (): void {
const foo = this as FooDocument;
foo.name = 'bar';
};
const FooModel = mongoose.model<FooDocument>('foos', fooSchema);
export default FooModel;
这样,您就可以将Foo
接口用于具有反演缺陷的方法。它们在您的存储库中将返回Foo
而不是 FooDocument...
另外:如果在数据库请求中使用lean()
,则返回的Foo
接口正好。有关 lean 的更多信息
您的UserClass
需要从 mongoose
扩展Model
。您似乎缺少一些必需的代码来使其为您工作。
从您作为参考共享的链接中,这里有一个指南,应该可以通过完整的代码示例解决您的问题。
https://stackoverflow.com/a/58107396/1919397