Как исключить определенное значение из вложенной схемы zod?

У меня есть следующая схема 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

Как я могу опустить это вложенное значение?

2 ответа

Минимальное изменение, которое должно работать, это:

      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>; 
Другие вопросы по тегам