如何使用Zod强制枚举所有值均为对象的必选键?
解决Zod中枚举值作为必填对象键的问题
你遇到的问题是因为z.record的设计初衷是允许任意数量符合键类型的属性,而非强制包含所有枚举值,所以TypeScript会将其推导为Partial<Record<...>>,导致每个键的类型都是string | undefined。
要实现“强制包含所有枚举值作为必填键”且不用逐个手动添加的需求,可以通过以下方式处理:
import { z } from "zod"; const countriesEnum = z.enum(["USA", "CAN", "MEX"]); // 利用枚举的options属性,动态生成包含所有枚举值的对象Schema const countryCapitalSchema = z.object( Object.fromEntries( countriesEnum.options.map(country => [country, z.string()]) ) ); const sampleObjectSchema = z.object({ countryToCapital: countryCapitalSchema }); // 类型验证:此时countryToCapital必须包含所有枚举值,且每个键的类型都是string type SampleObject = z.infer<typeof sampleObjectSchema>; // SampleObject['countryToCapital'] 类型为 { USA: string; CAN: string; MEX: string }
原理说明
countriesEnum.options会返回枚举的所有值组成的数组(["USA", "CAN", "MEX"])Object.fromEntries将数组转换为{ USA: z.string(), CAN: z.string(), MEX: z.string() }的结构z.object接收这个结构后,会生成一个强制包含所有键的对象Schema,而非Partial类型
这种方式既避免了手动逐个编写枚举键,又能确保对象必须包含所有枚举值作为必填属性。
内容的提问来源于stack exchange,提问作者BSimpson
相关产品推荐
相关产品推荐

