0

So, I have a custom advanced results page- it allows for /articles?name="" and so forth.

First time using TypeScript, so I am migrating my code over.

However, I get to the very last part, and it gives me a typescript error.

// eslint-disable-next-line no-unused-vars
import {Request, Response, NextFunction} from 'express';

// eslint-disable-next-line max-len
const advancedResults: any = (model: any, populate: string) => async (req: Request, res: Response, next: NextFunction) => {
  let query: any;

  // Copy req.query
  const reqQuery = {...req.query};

  // Fields to exclude
  const removeFields = ['select', 'sort', 'page', 'limit'];

  // Loop over removeFields and delete them from reqQuery
  removeFields.forEach((param) => delete reqQuery[param]);

  // Create query string
  let queryStr = JSON.stringify(reqQuery);

  // Create operators ($gt, $gte, etc)
  // eslint-disable-next-line max-len
  queryStr = queryStr.replace(/\b(gt|gte|lt|lte|in)\b/g, (match) => `$${match}`);

  // Finding resource
  query = model.find(JSON.parse(queryStr));

  // Select Fields
  if (req.query.select) {
    const fields = (<string>req.query.select).split(',').join(' ');
    query = query.select(fields);
  }

  // Sort
  if (req.query.sort) {
    const sortBy = (<string>req.query.sort).split(',').join(' ');
    query = query.sort(sortBy);
  } else {
    query = query.sort('-createdDate');
  }

  // Pagination
  const page = parseInt(<string>req.query.page, 10) || 1;
  const limit = parseInt(<string>req.query.limit, 10) || 25;
  const startIndex = (page - 1) * limit;
  const endIndex = page * limit;
  const total = await model.countDocuments();

  query = query.skip(startIndex).limit(limit);

  if (populate) {
    query = query.populate(populate);
  }

  // Executing query
  const results = await query;

  // Pagination result
  const pagination: any = {};

  if (endIndex < total) {
    pagination.next = {
      page: <any>page + 1,
      limit,
    };
  }

  if (startIndex > 0) {
    pagination.prev = {
      page: <any>page - 1,
      limit,
    };
  }

  res.advancedResults = { // Error here, Property 'advancedResults' does not exist on type 'Response<any>'
    success: true,
    count: results.length,
    pagination,
    data: results,
  };

  next();
};

export default advancedResults;

I have added any as the type... ect. am I doing something incorrect in the previous code? do I need to redo this entire function? let me know if this is correct. I have searched through the other questions that have the same line, and In my opinion, it does not answer my question. I think this is a special case. Thanks!

HonorableTones
  • 140
  • 3
  • 11
  • 1
    Do you want to add "express" as a tag here? If not, please consider modifying the above code so as not to be dependent on its specific typings. – jcalz Jun 16 '20 at 20:15
  • 1
    lol, that was a dumb mistake. I added express `import express, {Request, Response, NextFunction} from 'express';` but the error still occurs with the very last `res.advancedResults` and my `split()` is also having an error.. TypeScript is a huge pain. – HonorableTones Jun 16 '20 at 20:31
  • 1
    You're trying to do [something very similar to this question](https://stackoverflow.com/questions/37377731/extend-express-request-object-using-typescript/51050139#51050139), but with the `Response` type instead of `Request`. – Alex Wayne Jun 16 '20 at 20:37
  • That answer in the link you provided sees so complicated, so I have to must a custom response and import it in? – HonorableTones Jun 16 '20 at 20:42

1 Answers1

-1

As Alex Wayne posted in the comment above, and to anyone that runs across this thread. The answer lies in the link he provided: Here

Step 1: Go into your root folder/node_modules/@types/express/index.d.ts file.

Step 2: Add the following code AFTER export = e;

declare global{
    namespace Express {
        interface Response {
            yourCustomResponse: yourType
        }
    }
}

Step 3: After this is completed, save that file and navigate to your tsconfig.json.

Step 4: add to "typeRoots" this "./node_modules/@types to ensure that the global response is being read by TypeScript.

Hopefully this answers your question, and again I want to thank everyone that posted comments to me and helped me through this. @jcalz @Alex Wayne

More information can be found under Declaration Merging, in the Typescript Docs here

HonorableTones
  • 140
  • 3
  • 11