使用 Express 中间件验证请求对象时出现 Typescript 错误

Typescript error when validating a request object with Express Middleware

提问人:katrin_melody 提问时间:8/26/2023 最后编辑:katrin_melody 更新时间:8/28/2023 访问量:92

问:

我正在将我的应用程序从 js 移动到 ts,但遇到了以下问题:

在我的应用程序中,我使用中间件函数来验证请求。它检查是否存在、图像类型和图像大小等内容req.files.image

imageRouter.route('/upload').post(validateUploadImageData, uploadImage)

但是,当我移动到下一个函数时,我注意到打字稿错误。uploadImage'req.files' is possibly 'null' or 'undefined'.ts(18049)

我明白为什么会发生这种情况:ts 对我在另一个函数中的验证一无所知,它只是严格检查当前函数中的类型。但是,除了在每个中间件函数中执行相同的检查和类型缩小之外,是否有解决此问题的解决方法?

TypeScript Express 验证 类型缩小 请求验证

评论

0赞 MaximilianMairinger 8/28/2023
你可以通过编写来告诉编译器是什么。.这不会引入任何运行时开销。req.filesconst files = req.files as {image: ...}
0赞 MaximilianMairinger 8/28/2023
或者,如果 ts 知道正确的类型,但假设它也可能是 undefined/null。您可以使用速记来告诉 ts 编译器您知道该值不是未定义的。这也不会引入运行时开销。例:。为了完整起见:还有可选的 chaining (),它确实引入了运行时开销。!req.files!.imagesreq.files?.images

答:

0赞 katrin_melody 8/28/2023 #1

如果其他人正在寻找一个更优雅和类型安全的解决方案来解决这个问题,请查看 Zod: https://zod.dev 它是一个非常易于使用的模式声明和验证库,它缩小了打字稿和 javascript 之间的执行差距问题。

现在我的代码如下所示:

import { z } from 'zod'

export const ApplyFilterQueryShema = z.object({

    filterName: z.union([
        z.literal('greyscale'),
        z.literal('sepia'),
        z.literal('reflect'),
        z.literal('blur'),
    ]),
    imageName: z.string(),
})


//controllers file
import { ApplyFilterQueryShema } from '../shemas'

export const applyFilter = function (
    req: Request,
    res: Response,
    next: NextFunction
) {
    try {
        const { imageName, filterName } = ApplyFilterQueryShema.parse(req.query)
..........

它的作用基本上是验证我从 .因此,我们不需要在每个函数中进行 100 行验证,但同时又不会损害数据安全性ApplyFilterQueryShema.parse(req.query)