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.
