[英]Mongoose + Typescript -> Exporting model interface
I want to export only my model's interfaces instead of the Document so that nobody can modify my model if it's not inside it's own class methods.我只想导出我的模型的接口而不是文档,这样如果我的模型不在它自己的类方法中,那么没有人可以修改我的模型。 I have defined the interface and the schema like this:
我已经定义了这样的接口和架构:
IUser:用户:
interface IUser {
_id: string;
name: string;
email: string;
created_at: number;
updated_at: number;
last_login: number;
}
And the Schema:和架构:
let userSchema: Mongoose.Schema = new Mongoose.Schema({
'name': String,
'email': String,
'created_at': {'type': Date, 'default': Date.now},
'updated_at': {'type': Date, 'default': Date.now},
'last_login': {'type': Number, 'default': 0},
});
interface UserDocument extends IUser, Mongoose.Document {}
And then the model然后模型
// Model
let Users: Mongoose.Model<UserDocument> = Mongoose.model<UserDocument>('User', userSchema);
So i just export the IUser and a class User that basically has all the methods to update my model.所以我只是导出 IUser 和一个类 User,它基本上具有更新我的模型的所有方法。
The problem is that typescript complains if i add the _id to my interface, but i actually need it, otherwise i will need to pass the UserDocument and that's what i didn't wanted to do.问题是打字稿会抱怨,如果我将 _id 添加到我的界面中,但我实际上需要它,否则我将需要传递 UserDocument 而这正是我不想做的。 The error typescript gives me is:
错误打字稿给我的是:
error TS2320: Interface 'UserDocument' cannot simultaneously extend types 'IUser' and 'Document'.错误 TS2320:接口“UserDocument”不能同时扩展类型“IUser”和“Document”。 Named property '_id' of types 'IUser' and 'Document' are not identical.
“IUser”和“Document”类型的命名属性“_id”不相同。
Any ideas how i can add the _id property to my interface?任何想法如何将 _id 属性添加到我的界面?
Thanks!谢谢!
Try:尝试:
interface UserDocument extends IUser, Mongoose.Document {
_id: string;
}
It will resolve the conflict between IUser._id (string) vs Mongoose.Document._id (any).它将解决 IUser._id (string) 与 Mongoose.Document._id (any) 之间的冲突。
Update :更新:
As pointed out in comments, currently it gives a incompatible override for member from "Document"
, so another workaround must be used.正如评论中所指出的,目前它为
incompatible override for member from "Document"
提供了incompatible override for member from "Document"
,因此必须使用另一种解决方法。 Intersection types is a solution that can be used. 交叉点类型是一种可以使用的解决方案。 That said, the following can be done:
也就是说,可以执行以下操作:
type UserDocument = IUser & Mongoose.Document;
Alternatively, if you do not want UserDocument
anymore:或者,如果您不再需要
UserDocument
:
// Model
let Users = Mongoose.model<IUser & Mongoose.Document>('User', userSchema);
It is worth noting that there is a side effect in this solution.值得注意的是,此解决方案存在副作用。 The conflicting properties will have the types intersected, so
IUser._id (string) & Mongoose.Document._id (any)
results in UserDocument._id (any)
, for example.例如,冲突的属性将具有相交的类型,因此
IUser._id (string) & Mongoose.Document._id (any)
结果为UserDocument._id (any)
。
try this:试试这个:
const UserSchema: Schema = new Schema(
{
..
}
);
type UserDoc = IUser & Document;
export interface UserDocument extends UserDoc {}
// For model
export interface UserModel extends Model<UserDocument> {}
export default model<UserDocument>("User", UserSchema);
I just had this exact issue, where I wanted to keep the User interface properties as separate from Mongoose as possible.我刚刚遇到了这个确切的问题,我想让用户界面属性尽可能与 Mongoose 分开。 I managed to solve the problem using the Omit utility type.
我设法使用Omit实用程序类型解决了这个问题。
Here is your original code using that type:这是使用该类型的原始代码:
import { Document, Model, ObjectId } from 'mongoose';
export interface IUser {
_id: ObjectId;
name: string;
email: string;
created_at: number;
updated_at: number;
last_login: number;
}
export interface IUserDocument extends Omit<IUser, '_id'>, Document {}
export interface IUserModel extends Model<IUserDocument> {}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.