Shadow Fighter
Shadow Fighter

Reputation: 11

How can I override the typeof mongoose Model methods in typescript

const { Document, Model, default: mongoose } = require('mongoose');
//store reference to original 
const findOriginalMethod = Model.find;

// override the mongoose methods to accept response as the first parameter
UsersSchema.statics.find = async function (res,...args) {
  let self = this;
  const result = await findOriginalMethod.call(self, ...args);
  const historyData = {
    user: res.locals.user.userName,
    userId: res.locals.user._id,
    action: 'find',
    collectionName: 'Users',
  };


   historyData.data = result;
   historyData.documentId = result._id;
   // historyEmitter.emit('saveLog', historyData);

  return result;
}
import express from 'express';
import { Document, Model, default as mongoose } from 'mongoose';

//store reference to original 
const findOriginalMethod = Model.find;
//get the return type of the accessed method  
type findReturnType = ReturnType<typeof findOriginalMethod>;
//get the type parameters of the accessed method  
type findParamsType = Parameters<typeof findOriginalMethod>;

// override the mongoose methods to accept response as the first parameter
UsersSchema.statics.find = async function (res: express.Response, ...args: findParamsType): Promise<findReturnType> {
  let self = this;
  const result = await findOriginalMethod.call(self, ...args) as any;
  const historyData: any = {
    user: res.locals.user.userName,
    userId: res.locals.user._id,
    // db: res.locals.db,
    source: res.locals.payload.role,
    action: 'find',
    collectionName: 'Users',
  };

  historyData.data = result;
  historyData.documentId = result._id;

  return result;
}


export interface IUserMethods extends Model<IUser> {
  find(res: express.Response, ...args: findParamsType): Promise<findReturnType>;
}


// const Users = connection.model('Users') || connection.model('Users', UsersSchema);
const Users = connection.models.Users
  ? connection.model<IUser, IUserMethods>('Users')
  : connection.model<IUser, IUserMethods>(
    'Users',
    UsersSchema,
  );


export default Users;
Interface 'IUserMethods' incorrectly extends interface 'Model<IUser, {}, {}, {}, Document<unknown, {}, IUser> & IUser & { _id: ObjectId; }, any>'.
  The types returned by 'find(...)' are incompatible between these types.
    Type 'Promise<Query<unknown[], unknown, {}, any, "find">>' is missing the following properties from type 'Query<(FlattenMaps<IUser> & { _id: ObjectId; })[], any, {}, IUser, "find">': _mongooseOptions, exec, $where, all, and 86 more.
import mongoose from "mongoose";
import express from 'express';

declare global {
  namespace mongoose {
    interface Model<T> {
      find(res: express.Response, ...args: Parameters<typeof mongoose.Model.find>): Promise<ReturnType<typeof mongoose.Model.find>>
    }
  }
}

Upvotes: 1

Views: 72

Answers (0)

Related Questions