What does this error say? Type 'ParsedQs' is not assignable to type 'string'

12,289

Solution 1

req.query is an object containing request query

So if you send a request to the endpoint like this /?foo=bar&a=123

You can access the query value from

req.query.foo // bar
req.query.a // 123

You are passing query object to the $search, meanwhile you are supposed to pass a string, so it should be

Company.find({ $text: { $search: req.query.yourQueryKey as string } }).exec((err, docs) => {

Solution 2

You are passing req.query to your search and the default Typescript type for req.query is

Request<unknown, unknown, unknown, QueryString.ParsedQs, Record<string, any>>.query: QueryString.ParsedQs 

and if you passed in req.query.searchText the type for that would be

string | QueryString.ParsedQs | string[] | QueryString.ParsedQs[] | undefined

The simple way is already answered here just do

export const searching = (req: Request, res: Response) => { 
const searchText = req.query. searchText as string
  Company.find({ $text: { $search: searchText } }).exec((err, docs) => {
    if (docs) {
      res.status(200).json(docs)
    } else {
      console.log(err)
    }
  })
}

That works but gets sloppy when you have a lot of variables from your query params. In express try out the RequestHandler for your endpoints.

import { RequestHandler } from 'express'

interface QueryTypes {
  searchText: string
  moreSearchText: string
}
export const searching:RequestHandler<unknown, unknown, unknown, QueryTypes > = (req, res) => {
  Company.find({ $text: { $search: req.query } }).exec((err, docs) => {
    if (docs) {
      res.status(200).json(docs)
    } else {
      console.log(err)
    }
  })
}

You can see using the RequestHandler I can pass in a few unknown types and the fourth one I can pass in the query types. I can also remove the Request and Response types to just (req, res) because RequestHandler already types out the handler for us.

You're probably wondering what the 3 previous unknown are and that too in the typescript docs for RequestHandler. Here is the docs.

interface RequestHandler<P = core.ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = qs.ParsedQs, Locals extends Record<string, any> = Record<string, any>>

Now using RequestHandler. I can type out parameters, body, reqbody or query. Use a combo or skip them using unknown like I did in my example.

This also has the added benefit of giving you type safety so

const test = req.query.test

would highlight a typescript error in vscode for me because 'test' is defined in my QueryTypes interface.

Solution 3

Adding as any like as below might help you -

Company.find({ $text: { $search: req.query as any} }).exec((err, docs) => {
-------------
-------------
-------------

Solution 4

req.query is an object that contains all of query parameters you specified in the query.

If your request looks like this

test.com/search/?s=something

something will be stored in req.query.s.

The second option is to use named route parameters. So you can set do this:

Request URL

test.com/search/something

Route

app.get('/search/:search', (req, res) => {
   console.log(req.params.search); // "something". NB use req.params, not req.query
})
Share:
12,289

Related videos on Youtube

redlightfilms
Author by

redlightfilms

Updated on September 15, 2022

Comments

  • redlightfilms
    redlightfilms over 1 year

    Hello my problem is I want to use the search query of mongoose. But I want to make a get request using a query. Why is that not possible? I do not understand this error. I am using version 5.10.0 of mongoose. I don't want to do it as a post request and I would not like to use req.body. Can anyone help me?

    here my code:

    export const searching = (req: Request, res: Response) => {
      Company.find({ $text: { $search: req.query } }).exec((err, docs) => {
        if (docs) {
          res.status(200).json(docs)
        } else {
          console.log(err)
        }
      })
    }
    

    my error message:

    (property) $search: string
    No overload matches this call.
    The last overload gave the following error.
    Type 'ParsedQs' is not assignable to type 'string'.ts(2769)
    
  • redlightfilms
    redlightfilms over 3 years
    Yes but the problem is that even if I type req.query.foo or something like that I get the same error. This: No overload matches this call. The last overload gave the following error. Type 'string | ParsedQs | string[] | ParsedQs[] | undefined' is not assignable to type 'string'.
  • Owl
    Owl over 3 years
    Check my edit. You need to cast the type to string using as