2

I want to define custom query helper using query helper api . Here the example:

// models/article.ts

import { Document, Schema, Model, model } from 'mongoose';

interface IArticle extends Document {
   name: string;
}

interface IArticleModel extends Model<IArticle> {
   someStaticMethod(): Promise<any>;
}

const ArticleSchema = new Schema( { name: String } )

ArticleSchema.query.byName = function(name) {
    return this.find({ name })
}

export default model<IArticle, IArticleModel>('Article', ArticleSchema);



// routes/article.ts
import ArticleModel from '../models/article.ts'

router.get('/articles, (req, res) => {
    ArticleModel.find().byName('example')
})

Typescript complains about byName method when I chain it with defaults.
I can put it in IArticleModel interface but in that case I could only call it from model.
Where should I put the definition of this method to use it in chainable way?

Ivan Semochkin
  • 8,649
  • 3
  • 43
  • 75

1 Answers1

5

I've drafted a new version of @types/mongoose that supports query helpers. See this answer for ways to install a modified @types package. With my version, you should be able to write the following in models/article.ts:

import { Document, Schema, Model, model, DocumentQuery } from 'mongoose';

interface IArticle extends Document {
   name: string;
}

interface IArticleModel extends Model<IArticle, typeof articleQueryHelpers> {
   someStaticMethod(): Promise<any>;
}

const ArticleSchema = new Schema( { name: String } )

let articleQueryHelpers = {
    byName(this: DocumentQuery<any, IArticle>, name: string) {
        return this.find({ name });
    }
};
ArticleSchema.query = articleQueryHelpers;

export default model<IArticle, IArticleModel>('Article', ArticleSchema);

and then routes/article.ts will work. If this works for you, then I will submit a pull request to the original package on DefinitelyTyped.

Matt McCutchen
  • 28,856
  • 2
  • 68
  • 75