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

如何在Zod中基于其他字段定义字段并保证输出类型正确?

如何在Zod中基于其他字段定义字段并保证输出类型正确?

嘿,看你已经在折腾Zod的Schema扩展来区分不同职业状态了,要实现「根据某个字段的不同值,对应不同的字段结构」还保证TypeScript类型完全准确,Zod的**discriminated union(区分联合类型)**绝对是你要找的工具!它专门处理这种互斥结构的校验和类型推导,比单独写两个Schema再合并靠谱多了。

先给你调整后的完整代码示例(我补全了你没写完的salarieSchema部分,你可以根据实际需求修改):

// 先假设你的基础通用字段Schema是这样的(根据你的代码推测)
const baseProfessionalInformationSchema = z.object({
  name: z.string(),
  email: z.string().email(),
  // 其他所有职业状态都共享的字段...
});

// 独立从业者专属Schema
const independantSchema = baseProfessionalInformationSchema.extend({
  professional_status: z.literal('independant' satisfies ProfessionalStatus),
  profession: z.enum(
    Object.keys(PROFESSIONS.INDEPENDANTS) as [
      keyof typeof PROFESSIONS.INDEPENDANTS,
      ...Array<keyof typeof PROFESSIONS.INDEPENDANTS>
    ]
  ),
  date_creation_company: z.string(),
});

// 受雇者专属Schema
const salarieSchema = baseProfessionalInformationSchema.extend({
  professional_status: z.literal('salarie' satisfies ProfessionalStatus),
  employer_name: z.string(),
  hire_date: z.string(),
  // 其他受雇者专属的字段...
});

// 核心:用discriminatedUnion把两个Schema合并,指定区分字段是professional_status
const professionalInformationSchema = z.discriminatedUnion('professional_status', [
  independantSchema,
  salarieSchema,
]);

// 自动推导的类型完全正确,会根据professional_status区分两种结构
type ProfessionalInformation = z.infer<typeof professionalInformationSchema>;

为什么这个方案好用?

  • 校验精准:Zod会根据professional_status的值自动校验对应字段,比如如果状态是independant,就会强制检查date_creation_company,不会要求受雇者的employer_name,反之亦然,避免出现不符合结构的数据。
  • 类型安全:TypeScript会自动识别联合类型的分支——当你判断professional_status === 'independant'时,编辑器会自动提示该对象拥有date_creation_company字段,不会出现类型报错。

另外你原来写的z.enum部分是对的,通过类型断言把对象key转成元组类型,避免了Zod生成宽泛的字符串类型,保证了profession字段只能是PROFESSIONS.INDEPENDANTS的合法key。

如果以后遇到更复杂的字段依赖(比如某个字段可选与否取决于另一个字段),还可以用z.refine做自定义校验,但对于这种完全不同的结构,discriminated union是Zod官方推荐的最优解。

备注:内容来源于stack exchange,提问作者Jeromearsene

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 17:43:13