typescript 在路由方法之外定义Express请求处理程序时,自动推断请求参数的类型

1dkrff03  于 2023-01-18  发布在  TypeScript
关注(0)|答案(1)|浏览(97)

当我在对某个Express路由方法的调用中定义请求处理程序时,Typescript能够从路由推断req.params对象的结构:

import express from "express";
let app = express();

app.get("/:abc", (req, res) => {
    // req.params is inferred to be type { abc: string }
    let abc = req.params.abc; // this typechecks - good
    let xyz = req.params.xyz; // this doesn't - good
})

但是,当我在路由方法调用之外定义请求处理程序时,Express不会推断类型:

import express, { RequestHandler } from "express";
let app = express();

let requestHandler: RequestHandler = (req, res) => {
    // req.params is inferred to be type ParamsDictionary
    // which is equal to {[key: string]: string}
    // and thus too generic
    let abc = req.params.abc; // this typechecks - good
    let xyz = req.params.xyz; // this shouldn't, but does - bad
}
app.get("/:abc", requestHandler)

RequestHandler可选地接受泛型来输入请求和响应的部分,因此我可以通过显式传递RouteParameters类型和route字符串来让它对参数进行类型检查:

import express, { RequestHandler } from "express";
import { RouteParameters } from "express-serve-static-core/index.js";
let app = express();

let requestHandler: RequestHandler<RouteParameters<"/:abc">> = (req, res) => {
    // now typescript can infer that req.params is type { abc: string }
    let abc = req.params.abc; // this typechecks - good
    let xyz = req.params.xyz; // this doesn't - good
};
app.get("/:abc", requestHandler);

但是这需要我输入两次相同的路由,这不是什么大问题,但是我不喜欢没有类型检查来确保我传递给route方法的路由与我传递给RouteParameters的路由相同。

let requestHandler: RequestHandler<RouteParameters<"/:abc">> = (req, res) => {
    let abc = req.params.abc; // this typechecks - bad
};
app.get("/:jkl", requestHandler); // changed here

我没有得到类型错误,这是有意义的,但不是理想的。另外,如果我想通过添加额外的接口来为请求处理程序添加更多的类型检查,我可能必须在不止两个地方输入路由。
有没有什么方法可以让一个在路由方法调用之外定义的请求处理程序来推断req.params的类型,而不用显式地将RouteParameters<"route-string">泛型类型传递给它?

6vl6ewon

6vl6ewon1#

没有,但我通常所做的是将我的动态处理程序函数 Package 到另一个接受应用程序的函数中:

import { Express } from "express";

const requestHandlerFor = (app: Express) => app.get("/:abc", ...);

// ...

requestHandlerFor(app);

相关问题