mongoose icon indicating copy to clipboard operation
mongoose copied to clipboard

Does it work with descriminators, methods and statics?

Open JohnnyJumper opened this issue 7 months ago • 0 comments

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 };

JohnnyJumper avatar May 22 '25 17:05 JohnnyJumper