如何在Zod中表示Partial<Record<枚举类型, boolean>>?
使用Zod实现Partial<Record<SomeEnum, boolean>>的正确方式
问题场景
在TypeScript中,我们可以通过类型工具快速定义Partial<Record<SomeEnum, boolean>>:
type SomeEnum = 'one' | 'two'; type MyRecord = Record<SomeEnum, boolean>; type MyRecordPartial = Partial<MyRecord>;
但在Zod中,z.record()创建的Schema并没有内置的partial()方法,直接调用会报错:
import { z } from 'zod'; const SomeEnum = z.enum(['one', 'two']); const MyRecord = z.record(SomeEnum, z.boolean()); const MyRecordPartial = MyRecord.partial(); // ❌ Record类型不存在partial()方法
惯用解决方案
Zod中实现这类"枚举键可选Record"的标准做法是用z.object()配合枚举的可选字段,核心思路是把枚举的每个值转为可选的键值对:
基础实现
import { z } from 'zod'; const SomeEnum = z.enum(['one', 'two']); // 基于枚举值构建可选字段的对象Schema const MyRecordPartial = z.object( Object.fromEntries( SomeEnum.options.map(key => [key, z.boolean().optional()]) ) ); // 验证示例 MyRecordPartial.parse({ one: true }); // ✅ 验证通过 MyRecordPartial.parse({ two: false }); // ✅ 验证通过 MyRecordPartial.parse({}); // ✅ 空对象也合法 MyRecordPartial.parse({ three: true }); // ❌ 非法键,抛出验证错误
封装复用工具函数
如果需要多次创建这类Schema,可以封装成通用函数:
import { z, ZodEnum, ZodTypeAny } from 'zod'; function createPartialEnumRecord<T extends ZodEnum<any>, U extends ZodTypeAny>( enumSchema: T, valueSchema: U ) { return z.object( Object.fromEntries( enumSchema.options.map(key => [key, valueSchema.optional()]) ) ); } // 使用示例 const MyRecordPartial = createPartialEnumRecord(SomeEnum, z.boolean());
这种方式完美对应TypeScript中的Partial<Record<SomeEnum, boolean>>类型:既限制了键只能是枚举内的值,又允许所有键可选。
内容的提问来源于stack exchange,提问作者Yona Appletree
相关产品推荐
相关产品推荐

