如何在Zod中允许匹配正则的键并保留指定属性类型?
Zod 混合固定字段与正则匹配字段的验证方案
可以通过固定字段schema + 自定义校验 + 类型推断补充的方式实现需求,具体代码如下:
import { z } from "zod"; // 定义固定字段的验证规则 const fixedFields = z.object({ a: z.number(), b: z.number() }); // 匹配允许的额外键的正则 const metadataKeyPattern = /^metadata_hash_.*/; // 组合完整schema const schema = fixedFields // 添加自定义校验,确保所有额外键符合规则且值为字符串 .refine((obj) => { return Object.keys(obj).every((key) => { if (key === "a" || key === "b") return true; return metadataKeyPattern.test(key) && typeof obj[key] === "string"; }); }, { message: "所有额外字段必须以metadata_hash_开头,且值为字符串类型" }) // 补充TypeScript类型推断,让编辑器识别正则匹配的键类型 .merge(z.record(z.string().regex(metadataKeyPattern), z.string()));
方案说明
- 固定字段校验:先用
z.object定义a、b两个必填的数字字段,保证基础结构的正确性。 - 自定义键值校验:通过
.refine遍历对象所有键,对非固定字段做双重校验:键必须匹配metadata_hash_开头的正则,对应的值必须是字符串类型。 - 类型推断补充:用
.merge结合z.record完善TypeScript类型提示,让开发工具能识别出符合规则的额外键及其值类型,避免类型报错。
为什么之前的方法不适用
- 直接合并
object与record:Zod不允许两种结构冲突的schema直接合并,会抛出语法错误。 - 使用
.catchall:仅能校验额外字段的值类型,无法限制键的命名规则,不符合需求。 z.preprocess:会修改原始对象结构,破坏数据的原有格式,不满足业务要求。
内容的提问来源于stack exchange,提问作者jotjern
相关产品推荐
相关产品推荐

