mongoose
mongoose copied to clipboard
Does it work with descriminators, methods and statics?
I am contemplating trying out the library, but I heavily use discriminators, document methods, and model statistics. So I guess my question would be, will this library support the use case? For more context, how can I convert this example into Zod schemas?
import mongoose, { Schema, Document, Model } from 'mongoose';
// ---------- BASE ----------
interface BaseDoc extends Document {
kind: string;
name: string;
getDisplayName(): string;
}
interface BaseModelType extends Model<BaseDoc> {
findByName(name: string): Promise<BaseDoc[]>;
}
const BaseSchema = new Schema<BaseDoc>(
{
kind: { type: String, required: true },
name: { type: String, required: true },
},
{ discriminatorKey: 'kind', collection: 'entities' }
);
BaseSchema.methods.getDisplayName = function () {
return `[${this.kind}] ${this.name}`;
};
BaseSchema.statics.findByName = function (name: string) {
return this.find({ name });
};
const BaseModel = mongoose.model<BaseDoc, BaseModelType>('Base', BaseSchema);
// ---------- CAT ----------
interface CatDoc extends BaseDoc {
livesLeft: number;
isAlive(): boolean;
}
interface CatModelType extends Model<CatDoc> {
findAlive(): Promise<CatDoc[]>;
}
const CatSchema = new Schema<CatDoc>({
livesLeft: { type: Number, required: true },
});
CatSchema.methods.isAlive = function () {
return this.livesLeft > 0;
};
CatSchema.statics.findAlive = function () {
return this.find({ livesLeft: { $gt: 0 } });
};
const CatModel = BaseModel.discriminator<CatDoc, CatModelType>('Cat', CatSchema);
// ---------- DOG ----------
interface DogDoc extends BaseDoc {
favoriteToy: string;
bark(): string;
}
interface DogModelType extends Model<DogDoc> {
findWithToy(toy: string): Promise<DogDoc[]>;
}
const DogSchema = new Schema<DogDoc>({
favoriteToy: { type: String, required: true },
});
DogSchema.methods.bark = function () {
return `${this.name} says: Woof!`;
};
DogSchema.statics.findWithToy = function (toy: string) {
return this.find({ favoriteToy: toy });
};
const DogModel = BaseModel.discriminator<DogDoc, DogModelType>('Dog', DogSchema);
// Export
export { BaseModel, CatModel, DogModel };