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

基于外部枚举值定义内部对象键的Zod类型解析问题

基于外部枚举值定义内部对象键的Zod类型解析问题

嘿,我看你在纠结用Zod解析API返回数据的问题——想用自定义枚举约束外层对象的键,同时每个键对应的内部对象还要有和外层键关联的{key}-action属性对吧?我来给你一步步讲怎么实现:

首先先明确你的场景:

API返回的数据格式是这样的:

{
  "title": {
    "title-action": "some value",
    ...rest
  },
  "body": {
    "body-action": "some value",
    ...rest
  }
}

你提到的Zod枚举应该是要补全成这样:

const MyEnum = z.enum(["title", "body"]);

解决方案一:动态生成严格匹配的Schema

这个方法能精准对应枚举里的每个键,同时让内部对象的{key}-action键和外层键自动关联,类型提示也更友好:

// 先提取枚举的字面量类型,方便后续复用
type MyEnumType = z.infer<typeof MyEnum>;

// 写个小函数,根据枚举键动态生成对应内部对象的Schema
const createInnerSchema = (key: MyEnumType) => 
  z.object({
    [`${key}-action`]: z.string(), // 自动拼接出和外层键对应的action键
    rest: z.record(z.unknown()).optional() // 处理你提到的...rest部分,可换成具体类型
  });

// 遍历枚举的所有选项,构建最终的API响应Schema
const apiResponseSchema = z.object(
  Object.fromEntries(
    MyEnum.options.map(key => [key, createInnerSchema(key)])
  )
).strict(); // 加上.strict()可以禁止API返回枚举外的多余键,按需选择

// 测试下解析效果
const testData = {
  "title": {
    "title-action": "some title content",
    rest: { extra: "title info" }
  },
  "body": {
    "body-action": "some body content"
  }
};

const parsedResult = apiResponseSchema.parse(testData);
console.log(parsedResult.title["title-action"]); // 输出 "some title content"

方法二:宽松匹配的Record方式(适合快速开发)

如果你对键的严格性要求不高,只是需要确保外层键是枚举值,内部结构相对统一,也可以用z.record快速实现:

// 定义通用的内部对象Schema
const innerSchema = z.object({
  // 注意:这种方式没法让内部键和外层键动态关联,适合内部键不依赖外层的场景
  action: z.string(),
  rest: z.record(z.unknown()).optional()
});

// 直接用枚举作为键类型,内部用通用Schema
const apiResponseSchema = z.record(MyEnum, innerSchema);

小提示

  • 如果你的...rest有固定的结构(比如有特定键和类型),直接把z.record(z.unknown())换成对应的z.object({ ... })就行。
  • 方法一生成的是严格对象类型,TypeScript会自动提示外层只能用枚举内的键,内部对象的{key}-action也会有精准提示,开发体验更好。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 13:04:52