Node.js使用MongoDB时如何校验查询结果是否符合自定义TypeScript类型要求
TypeScript 的类型断言仅在编译阶段生效,没有运行时校验能力,你需要添加运行时校验逻辑来保证返回的文档符合 Game 类型要求,以下是几种常用的实现方案:
方案1:手动实现类型守卫校验
无需引入额外依赖,适合字段较少的场景,通过自定义类型守卫函数逐个检查必填字段的存在性和类型:
export type Game = { name: string; description: string; // 其他必填字段 } // 类型守卫函数 function isGame(doc: unknown): doc is Game { if (typeof doc !== 'object' || doc === null) return false; const target = doc as Game; return typeof target.name === 'string' && typeof target.description === 'string'; // 其他字段的校验规则依次补充 }
查询后批量校验的代码示例:
const rawDocs = await this.games.find({}).toArray(); // 要求所有文档都合法,不合法直接抛出异常 if (!rawDocs.every(isGame)) { throw new Error('查询返回的文档存在不符合Game类型要求的字段'); } const games = rawDocs as Game[]; // 如果需要过滤合法文档、收集非法文档可以用以下逻辑 // const games = rawDocs.filter(isGame); // const invalidDocs = rawDocs.filter(doc => !isGame(doc));
方案2:使用运行时Schema校验库
如果Game类型字段较多,手动写校验逻辑成本高,可以用Zod、Yup这类运行时校验库,还能直接从Schema生成TypeScript类型,避免校验规则和类型定义不一致的问题,以Zod为例:
- 先安装依赖:
npm install zod - 定义Schema并导出对应的TS类型:
import { z } from 'zod'; const GameSchema = z.object({ name: z.string(), description: z.string(), // 支持配置更多校验规则,比如长度限制、枚举、数字范围等 }); // 直接从Schema生成Game类型,不用重复定义 export type Game = z.infer<typeof GameSchema>;
- 查询后执行校验:
const rawDocs = await this.games.find({}).toArray(); // 批量校验,任意文档不合法会直接抛出异常 const games = GameSchema.array().parse(rawDocs); // 如需获取错误信息不直接抛错,可以用safeParse方法 const parseResult = GameSchema.array().safeParse(rawDocs); if (!parseResult.success) { console.error('校验失败详情:', parseResult.error.issues); // 自定义错误处理逻辑 } else { const games = parseResult.data; }
方案3:MongoDB集合层面加Schema校验
你也可以直接在MongoDB集合上配置JSON Schema校验规则,从数据写入层就保证所有存入的文档符合要求,后续查询就不需要再额外做校验,示例配置:
db.createCollection("games", { validator: { $jsonSchema: { bsonType: "object", // 配置必填字段 required: ["name", "description"], properties: { name: { bsonType: "string", description: "名称为必填字符串字段" }, description: { bsonType: "string", description: "描述为必填字符串字段" } // 其他字段的规则依次补充 } } }, // 配置校验级别,strict表示所有写入都必须符合规则 validationLevel: "strict", validationAction: "error" })
该方案适合要求数据库层面保证数据一致性的场景,写入不符合规则的数据时MongoDB会直接抛出异常,需要配套处理写入侧的错误逻辑。
内容的提问来源于stack exchange,提问作者user991047
相关产品推荐
相关产品推荐

