如何从嵌套的 zod 方案中省略某些值?

How omit certain value from nested zod scheme?

我有以下 zod 架构,在某些情况下,我想从架构中完全省略一个字段。 我不能让它成为可选的。我怀疑有一些方法可以直接用 zod 来完成。有没有办法省略字段或以某种方式预处理架构?

例如,我如何在没有这个嵌套字段的情况下使用这个架构。

const schema = z.object({
  name: z.number(),
  age: z.number(),
  data: z.array(
    z.object({
      id: z.string().optional(),
      name: z.string().nonempty().optional(),
    })
  )
});

const test = schema.shape.data //. ??? how can I omit the name field? 
type typeTest = z.infer<typeof test>; // just data without name field

如何省略这个嵌套值?

使之有效的最小更改是:

const test = schema.shape.data.element.omit({ name: true }).array();

但另一种选择是将您的模式重新组织为几个命名部分并使用 merge 将它们组合起来,例如:

import { z } from 'zod';

const dataSchema = z.object({
  id: z.string().optional(),
  someOtherField: z.number(),
});

const namedSchema = z.object({
  name: z.string().nonempty().optional(),
});

const fullDataSchema = dataSchema.merge(namedSchema);

type Data = z.TypeOf<typeof dataSchema>;
type FullData = z.TypeOf<typeof fullDataSchema>;

另一个选项是在您的基本数据模式类型上使用 omit 来获取没有该字段的模式,然后在生成的模式上使用 typeof。如果你想在不同的场景中使用这些模式,我建议给它们命名。

import { z } from 'zod';

const dataSchema = z.object({
  id: z.string().optional(),
  someOtherField: z.number(),
  name: z.string().nonempty().optional(),
});

const noNameDataSchema = dataSchema.omit({ name: true });

type Data = z.TypeOf<typeof noNameDataSchema>;

这两种方法各有利弊,但结果应该是一样的。 (我个人发现自己更经常做前者,因为我发现代码更容易理解)

正确答案

const schema = z.object({
  name: z.number(),
  age: z.number(),
  data: z.array(
    z.object({
      id: z.string().optional(),
      name: z.string().nonempty().optional()
    })
  )
});

const test = schema.shape.data.element.omit({ name: true }).array(); 
type typeTest = z.infer<typeof test>;