javascript - Vad säger detta fel? Typen 'ParsedQs' kan inte tilldelas typen 'string'


Hej mitt problem är att jag vill använda sökfrågan i mongoose. Men jag vill göra en GET-förfrågan med en fråga. Varför är det inte möjligt? Jag förstår inte det här felet. Jag använder version 5.10.0 av mongoose. Jag vill inte göra det som en POST-förfrågan och jag skulle inte vilja använda req.body. Kan någon hjälpa mig?

här är min kod:

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)
    }
  })
}

mitt felmeddelande:

(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)

Svar #1

req.query är ett objekt som innehåller förfrågningsfrågor

Så om du skickar en begäran till ändpunkten som denna /?foo=bar&a=123

Du kan komma åt förfrågningsvärdet från

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

Du skickar frågeobjektet till $search, medan du egentligen ska skicka en sträng, så det bör vara

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

En bättre lösning är att skriva din RequestHandler-funktion

import {RequestHandler} from "express";

type Params = {};
type ResBody = {};
type ReqBody = {};
type ReqQuery = {
    query: string;
}

export const searching: RequestHandler<Params, ResBody, ReqBody, ReqQuery> = (req, res) => {
    const query = req.query.query; // string
}

Ännu bättre lösning: skriv din RequestHandler-funktion och använd ett valideringsbibliotek för att validera förfrågningsparametrarna, som joi eller celebrate

Svar #2

Du skickar req.query till din sökning och standardtypen i Typescript för req.query är

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

och om du skickade in req.query.searchText skulle typen för det vara

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

Det enkla sättet har redan besvarats här, gör bara

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)
    }
  })
}

Det fungerar men blir slarvigt när du har många variabler från dina query-parametrar. I Express, prova RequestHandler för dina 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)
    }
  })
}

Du kan se att genom att använda RequestHandler kan jag skicka in några okända typer och den fjärde kan jag skicka in förfrågningstyperna. Jag kan också ta bort Request- och Response-typerna till bara (req, res) eftersom RequestHandler redan typifierar hanteraren åt oss.

Du undrar förmodligen vilka de 3 tidigare okända är och det också i TypeScript-dokumentationen för RequestHandler. Här är dokumentationen.

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

Nu använder jag RequestHandler. Jag kan skriva ut parametrar, body, reqbody eller query. Använd en kombination eller hoppa över dem med unknown som jag gjorde i mitt exempel.

Detta har också den ytterligare fördelen att ge dig typ-säkerhet så

const test = req.query.test

skulle markera ett TypeScript-fel i VSCode för mig eftersom 'test' är definierad i mitt QueryTypes-gränssnitt.

Relaterade artiklar