MongoDB aggregation with typescript

Viewed 3512

I have a User model and I want to perform generic aggregation. mean any array of object I pass to this function it executes.

this is the sample of getUser function

public async getUser(aggregate: object): Promise<ResponseDTO> {
     let response = {} as ResponseDTO;
     const [err, user] = await To(User.aggregate(aggregate));
     if (user) {
         response = { success: true, data: user, message: "User fround" };
     }
     else
         response = { success: false, message: "User not fround" };
     return response;
}

and I pass this as a Parameter

const query = [
  {
     $match: {
        name:"Jon"
     }
  },
  {
    $project:{
      _id:1  
    }
  }
]
const userRes = await getUser(query);

But I'm not able to run the program it's giving me syntax error on getUser function

*(method) Model<any, any, any>.aggregate(pipeline?: any[] | undefined): Aggregate<any[]> (+1 overload)

Argument of type 'Aggregate<any[]>' is not assignable to parameter of type 'Promise'. Type 'Aggregate<any[]>' is missing the following properties from type 'Promise': [Symbol.toStringTag], finally*

I tried to change object to any, Array or Array in getUser parameter

here is the SS of the Error enter image description here

PS: I'm using node with typescript and IDE is VSCode

2 Answers

Mongoose queries have their own types, and you should use those types to avoid such errors.

You can import those types for anything you need directly from Mongoose package.

I strongly recommend using the Typegoose package, which helps to create fully typed MongoDB schemas. and by that allow you to use those types as a response, find and update queries and much more! reference: https://typegoose.github.io/typegoose/docs/guides/quick-start-guide

Example for your usage with correct type:

import { FilterQuery } from 'mongoose';

public async getUser(aggregate: FilterQuery<ResponseDTO>): Promise<ResponseDTO> {
     let response = {} as ResponseDTO;
     const [err, user] = await To(User.aggregate(aggregate));
     if (user) {
         response = { success: true, data: user, message: "User fround" };
     }
     else
         response = { success: false, message: "User not fround" };
     return response;
}

Mongoose provides PipelineStage interface for pipes We can use that right away

import { PipelineStage } from "mongoose";

public async getUser(aggregate: PipelineStage[]):
Promise<ResponseDTO> {
     let response = {} as ResponseDTO;
     const [err, user] = await User.aggregate(aggregate);
     if (user) {
         response = { success: true, data: user, message: "User found" };
     }
     else
         response = { success: false, message: "User not found" };
     return response;
}
Related