How to type `request.query` in express using TypeScript?
10,571
Solution 1
The solution is to use generics in the following manner.
const router = Router();
interface Foo {
foo: string;
}
function getHandler(request: Request<{}, {}, {}, Foo>, response: Response) {
const { query } = request;
query.foo;
}
router.route('/')
.get(getHandler)
Solution 2
you can do it like this :-
interface Query {
param1:string;
param2:string;
};
function getHandler(request: Request, response: Response) {
const {param1,param2} = request.query as unknown as Query;
}
Solution 3
I like to use the following approach in my projects.
const { url } = req.query;
if (typeof url !== "string") {
throw new ServerError("Query param 'url' has to be of type string", 400);
}
After checking the type TypeScript won't complain any more for this scope.
Author by
marcobiedermann
Full-Stack JavaScript Engineer with focus on React, Redux & Node.js and passioned about Open Source working @Mobimeo based in Berlin, Germany
Updated on June 20, 2022Comments
-
marcobiedermann about 2 years
I'm running an
express.js
application using TypeScript. Every time I try to processrequest.query.foo
I get the following error:Argument of type 'string | ParsedQs | string[] | ParsedQs[] | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable to type 'string'.
Setup:
import { Request, Response, Router } from 'express'; const router = Router(); function getHandler(request: Request, response: Response) { const { query } = request; query.foo; // string | QueryString.ParsedQs | string[] | QueryString.ParsedQs[] | undefined } router.route('/') .get(getHandler)
Is there a proper way to type
request.query
without casting? -
tim.rohrer over 3 yearsHave you tested this? I'm trying to use this approach and getting the error:
Type 'Request' is not generic.
-
Hongbo Miao over 3 yearsTested on @types/express 4.17.11. Works great! BTW, it would be better to use
Request<unknown, unknown, unknown, Foo>
. Otherwise, the ESLint will give error: Don't use{}
as a type.{}
actually means "any non-nullish value". -
Silviu Burcea almost 3 yearsOr
const getHandler: RequestHandler<unknown, unknown, unknown, Foo> = (req, res) => { ... }
-
tim.rohrer almost 3 yearsFor anyone else who reads my comment and wonders...it turns out I had not imported
Request
from the Express types, and so Fetch type of Request was being used. -
marcobiedermann almost 3 yearsYeah, I know, but I would like to avoid type casting
-
DaDo almost 3 yearsThis only works for the query object. How would I do this for the params and body objects?
-
tim.rohrer over 2 yearsSimilar to @HongboMiao, I arrived at a similar ESLint complaint, but believe that instead of using
unknown
for each, wouldn'tRecord<string, unknown>
be better as these should always be objects, right? -
s27840 over 2 yearsIf you get
Type 'Request' is not generic.
addimport type { Request } from "express";
-
Todd Rylaarsdam about 2 yearsThis is a good approach. Handles types well, and is nice and simple
-
oyalhi about 2 yearsit's a good practice to make params such as
foo?: string
optional, since they may not be present.