如何在Express中校验请求Body是否符合指定TypeScript类型?
验证Express请求Body符合TypeScript类型的方案
由于TypeScript类型仅存在于编译阶段,无法直接在运行时用来验证请求Body,你需要使用运行时类型验证工具来实现需求。以下是几个常用工具及对应实现:
1. Zod(现代主流方案)
Zod支持从验证规则自动推导TS类型,也可以反向关联,完美适配你的场景。
先安装依赖:
npm install zod
实现代码:
import { z } from "zod"; import express from "express"; const app = express(); app.use(express.json()); // 定义Zod验证规则 const SampleRequestBodySchema = z.object({ id: z.string(), name: z.string(), age: z.number(), address: z.object({ city: z.string(), street_num: z.number(), street_name: z.string(), }), balance: z.number().optional(), }); // 从规则导出TS类型 type SampleRequestBody = z.infer<typeof SampleRequestBodySchema>; app.post("/", (req, res) => { const validationResult = SampleRequestBodySchema.safeParse(req.body); if (validationResult.success) { res.status(200).send("Correct Type!"); } else { res.status(400).send(`Incorrect Type: ${validationResult.error.message}`); } }); app.listen(3000);
2. Yup(老牌验证库)
Yup采用链式调用API,是成熟的表单/请求验证工具。
安装依赖:
npm install yup
实现代码:
import * as yup from "yup"; import express from "express"; const app = express(); app.use(express.json()); const SampleRequestBodySchema = yup.object({ id: yup.string().required(), name: yup.string().required(), age: yup.number().required(), address: yup.object({ city: yup.string().required(), street_num: yup.number().required(), street_name: yup.string().required(), }).required(), balance: yup.number().optional(), }); // 导出TS类型 type SampleRequestBody = yup.InferType<typeof SampleRequestBodySchema>; app.post("/", async (req, res) => { try { await SampleRequestBodySchema.validate(req.body, { abortEarly: false }); res.status(200).send("Correct Type!"); } catch (err) { res.status(400).send(`Incorrect Type: ${err.message}`); } }); app.listen(3000);
3. io-ts(函数式风格验证库)
io-ts基于函数式编程思想,适合对类型安全要求极高的场景。
安装依赖:
npm install io-ts fp-ts
实现代码:
import * as t from "io-ts"; import { isRight } from "fp-ts/Either"; import express from "express"; const app = express(); app.use(express.json()); // 定义io-ts验证类型 const SampleRequestBody = t.type({ id: t.string, name: t.string, age: t.number, address: t.type({ city: t.string, street_num: t.number, street_name: t.string, }), }).partial({ balance: t.number, }); // 导出TS类型 type SampleRequestBody = t.TypeOf<typeof SampleRequestBody>; app.post("/", (req, res) => { const validationResult = SampleRequestBody.decode(req.body); if (isRight(validationResult)) { res.status(200).send("Correct Type!"); } else { res.status(400).send("Incorrect Type!"); } }); app.listen(3000);
以上方案均能确保必填字段存在且类型完全匹配,同时支持可选字段的验证逻辑,完全覆盖你的核心需求。
内容的提问来源于stack exchange,提问作者Wisam Jbori
相关产品推荐
相关产品推荐

