You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何TypeScript接口未校验请求体,不符合时无报错?

为什么TypeScript没对不符合接口的请求体报错?

核心原因有三个:

  • TypeScript结构类型的特性:TS采用鸭子类型机制,只要对象包含接口要求的所有必填字段,就算多了额外字段,也会被判定为符合接口。TS不会主动校验「是否存在额外字段」,它只关注你有没有满足接口的必填项。
  • 编译时检查,运行时无类型:TS的类型检查仅在编译阶段生效,部署后代码会被转成纯JavaScript,接口这类类型定义会被完全移除,运行时根本没有类型信息能用来校验请求体。你代码里的const newTransaction:NewTransactionPayload = req.body只是编译时的类型标注,运行时不会对req.body做任何过滤或校验。
  • 未添加运行时校验逻辑:你现在的代码只是给变量加了类型注解,但没有写任何运行时的校验逻辑。TS本身不提供运行时的请求体校验,要确保请求体严格符合接口,得自己手动过滤字段,或者用Zod、Joi这类专门的校验库来做运行时检查。

解决办法示例:

手动过滤字段

transactionsRouter.post('/', (req, res)=>{
    try {
        // 手动提取接口规定的字段,过滤掉额外内容
        const { transactionAmount, transactionDate, transactionWallet, transactionPocket, transactionTag, transactionDetails } = req.body;
        const newTransaction:NewTransactionPayload = {
            transactionAmount,
            transactionDate,
            transactionWallet,
            transactionPocket,
            transactionTag,
            transactionDetails
        };
        res.status(201).json(newTransaction);
    } catch (err){
        res.status(400).json({error: `Bad request. ${err}`})
    }
});

用Zod做运行时校验

import { z } from "zod";

// 定义Zod schema(同时支持编译时类型和运行时校验)
const NewTransactionSchema = z.object({
  transactionAmount: z.number(),
  transactionDate: z.string(),
  transactionWallet: z.string(),
  transactionPocket: z.string(),
  transactionTag: z.string(),
  transactionDetails: z.string(),
});

// 从schema生成TS类型
type NewTransactionPayload = z.infer<typeof NewTransactionSchema>;

transactionsRouter.post('/', (req, res)=>{
    try {
        // 运行时校验请求体,不符合会抛出错误
        const newTransaction = NewTransactionSchema.parse(req.body);
        res.status(201).json(newTransaction);
    } catch (err){
        res.status(400).json({error: `Bad request. ${err}`})
    }
});

内容的提问来源于stack exchange,提问作者gfek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:33:26