我试图找到一种优雅的方式来获取智能感知并使用我包装在类中以实现业务逻辑的猫鼬文档进行打字。这是我想出的解决方案,感觉有点老套,但似乎有效。这样可以吗还是有更好的方法?
最关键和hacky感觉的部分就是这个
type UserDocument = IUser & Document<IUser>;
import mongoose, {Document, model, Schema} from "mongoose";
interface IUser {
firstName: string
}
const userSchema = new Schema<IUser>({
firstName: {type: String, required: true}
});
const DbUser = mongoose.models.User || model<IUser>('User', userSchema);
type UserDocument = IUser & Document<IUser>;
export class User {
private userData: UserDocument = new DbUser();
public set firstName(value: string) {
this.userData.firstName = value;
}
public get firstName() {
return this.userData.firstName;
}
public static async createFromDocument(document: UserDocument): Promise<User> {
const user = new User();
user.userData = document;
return user;
}
public async save(): Promise<void> {
await this.userData.save();
}
}
在许多项目中,我使用此模板来构建模型和类型并使智能感知识别它:
import { Schema, model, Types } from 'mongoose';
import { ApiScanDocument } from './interfaces/index';
const ApiScansSchema = new Schema({
apiKeyId: {
type: Types.ObjectId,
required: true
},
scans: {
type: Number,
required: true
},
createdAt: {
type: Date,
default: Date.now
}
}, { toJSON: { virtuals: true }, toObject: { virtuals: true } });
ApiScansSchema.virtual('apiKey', {
ref: 'ApiKey',
localField: 'apiKeyId',
foreignField: '_id',
justOne: true
});
const ApiScan = model<ApiScanDocument>('ApiScan', ApiScansSchema);
export { ApiScan }
现在的类型:
import { Document, Types } from 'mongoose';
export interface ApiScanDocument extends Document {
apiKeyId: Types.ObjectId;
scans: number;
}
这与您的非常相似,但是使用 findOne 或 mongoose 的 find 方法找到的所有文档都具有默认类型