How to add types for mongoose 'Query<any>'

Viewed 190

I am trying to add a cache layer to my typescript project. when I search I found an article on medium How to add a Redis cache layer to Mongoose in Node.js

he implements cache by adding a function to mongoose.Query.prototype

mongoose.Query.prototype.cache = function(options = { time: 60 }) {
  this.useCache = true;
  this.time = options.time;
  this.hashKey = JSON.stringify(options.key || this.mongooseCollection.name);

  return this;
};

then in mongoose.Query.prototype.exec check the query is enabled caching or not

mongoose.Query.prototype.exec = async function() {
    if (!this.useCache) {
        return await exec.apply(this, arguments);
    }

    const key = JSON.stringify({
        ...this.getFilter(),
    });
    console.log(this.getFilter());
    console.log(this.hashKey);

    const cacheValue = await client.hget(this.hashKey, key);

    if (cacheValue) {
        const doc = JSON.parse(cacheValue);

        console.log("Response from Redis");
        return Array.isArray(doc)
            ? doc.map((d) => new this.model(d))
            : new this.model(doc);
    }

    const result = await exec.apply(this, arguments);
    return result;
};

Now enable caching by calling cache() function in the mongoose query

 books = await Book.find({ author: req.query.author }).cache();

Everything works fine, then I try to convert it to typescript but I don't know how to add type definitions for it

the typescript version always gives an error

Property 'cache' does not exist on type 'Query<any>',
Property 'useCache' does not exist on type 'Query<any>',
Property 'hashKey' does not exist on type 'Query<any>',

Is there any way to add these types to 'Query'?Please help me

1 Answers

I eventually got this working by doing the following. Also see https://stackoverflow.com/a/70656849/1435970

Create the file /src/@types/mongoose.d.ts and add the following to it:

type CacheOptions = {key?: string; time?: number}

declare module 'mongoose' {
  interface DocumentQuery<T, DocType extends import('mongoose').Document, QueryHelpers = {}> {
    mongooseCollection: {
      name: any
    }
    cache(options?: CacheOptions): any
    useCache: boolean
    hashKey: string
  }

  interface Query<ResultType, DocType, THelpers = {}, RawDocType = DocType> extends DocumentQuery<any, any> {}
}

Related