如何使用 TypeScript 在 express 中键入`request.query`?

mar*_*ann 13 url types request express typescript

我正在express.js使用 TypeScript运行一个应用程序。每次我尝试处理时request.query.foo,都会收到以下错误:

Argument of type 'string | ParsedQs | string[] | ParsedQs[] | undefined' is not assignable to parameter of type 'string'.
  Type 'undefined' is not assignable to type 'string'.
Run Code Online (Sandbox Code Playgroud)

设置:

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)
Run Code Online (Sandbox Code Playgroud)

有没有正确的打字方法request.query而不需要强制转换?

mar*_*ann 23

定义

Request是一个接受附加定义的泛型:

interface Request<
  P = core.ParamsDictionary,
  ResBody = any,
  ReqBody = any,
  ReqQuery = core.Query,
  Locals extends Record<string, any> = Record<string, any>
> extends core.Request<P, ResBody, ReqBody, ReqQuery, Locals> {}
Run Code Online (Sandbox Code Playgroud)

来源: https: //github.com/DefinitelyTyped/DefinitelyTyped/blob/89a4f41af507e68daf5f4794ad257f48920275f2/types/express/index.d.ts#L113-L118

例子

interface RequestParams {}

interface ResponseBody {}

interface RequestBody {}

interface RequestQuery {
  foo: string;
}

function getHandler(
  request: Request<RequestParams, ResponseBody, RequestBody, RequestQuery>,
  response: Response
) {
  const { query } = request;

  query.foo; // string
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*hli 13

我喜欢在我的项目中使用以下方法。

  const { url } = req.query;
  
  if (typeof url !== "string") {
    throw new ServerError("Query param 'url' has to be of type string", 400);
  }
Run Code Online (Sandbox Code Playgroud)

检查类型后,TypeScript 不会再抱怨此范围。


use*_*888 11

解决方案是按以下方式使用泛型。

const router = Router();

interface Foo {
    foo: string;
}

function getHandler(request: Request<{}, {}, {}, Foo>, response: Response) {
  const { query } = request;

  query.foo;

}

router.route('/')
  .get(getHandler)
Run Code Online (Sandbox Code Playgroud)

  • 在 @types/express 4.17.11 上测试。效果很好!顺便说一句,最好使用“Request&lt;unknown,unknown,unknown,Foo&gt;”。否则,ESLint 将给出错误:不要使用 `{}` 作为类型。`{}` 实际上意味着“任何非空值”。 (6认同)
  • 你测试过这个吗?我正在尝试使用这种方法并收到错误:“类型‘请求’不是通用的。” (3认同)
  • 这只适用于查询对象。我该如何对参数和主体对象执行此操作? (2认同)

小智 5

你可以这样做:-

interface Query {
   param1:string;
   param2:string;
};

function getHandler(request: Request, response: Response) {
   const {param1,param2} = request.query as unknown as Query;
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,我知道,但我想避免类型转换 (4认同)
  • 每次你使用“as”时,你基本上都会覆盖类型系统,所以你应该只将它作为最后的手段。这是搬起石头砸自己脚的好方法。如果可以的话,请使用新的“满足”。但这在这种情况下没有帮助。 (2认同)