如何在 Zod 中创建具有默认值的可选属性

Dan*_*515 10 typescript zod

我正在使用Zod,我想为用户输入定义一种架构,该架构具有一个带有默认值的可选字段。但是,我不可能使运行时行为与推断的类型相匹配。我想要的是该字段是可选的,并且当未提供或未定义时,使用默认值。如果我想要这种行为,我不能在生成的类型中使该字段可选,并且如果我设法使其在生成的类型中可选,那么它将在运行时不会获得默认值。

我用代码来解释一下:

import { Timestamp } from 'firebase/firestore';
import { z } from 'zod';

export const someSchema = z.object({
  id: z.string(),
  timestamp: z.instanceof(Timestamp),
  type: z.enum(['fever', 'constipation']),
  notes: z.string().optional().default(''),
});

export const someInput = someSchema
  .omit({ id: true })
  .merge(
    z.object({
      timestamp: z
        .date()
        .optional()
        .default(() => new Date()),
    }),
  )
  .partial({
    notes: true,
  });

export const schemaArray = z.array(someSchema);

export type Schema = z.infer<typeof someSchema>;
export type SchemaInput = z.infer<typeof someInput>; // <- Here I expect timestamp to be optional, but it is required


function a({ type, timestamp, notes}: SchemaInput){
  someInput.parse({
  type, timestamp, notes
  })
}

a({type: 'fever'}) <- Error, timestamp is required

Run Code Online (Sandbox Code Playgroud)

Dan*_*515 16

正如我在 github 上指出的那样,模式通常有输入和输出类型。默认情况下,z.infer返回输出类型,这可能是最常见的使用场景。值得庆幸的是,还有一种方法可以提取解析器的预期输入,而这正是我所需要的:

export type SchemaInput = z.input<typeof someInput>;

function a({ type, timestamp, notes}: SchemaInput){
  someInput.parse({
  type, timestamp, notes
  })
Run Code Online (Sandbox Code Playgroud)

现在推断的模式如下所示:

type SchemaInput = {
    timestamp?: Date | undefined;
    notes?: string | undefined;
    type: "fever" | "constipation";
}
Run Code Online (Sandbox Code Playgroud)

这正是我所需要的接受此输入并使用验证器来确保其具有正确格式的函数。

  • 编辑:您想使用“z.input&lt;typeof someInput&gt;”或“z.output&lt;typeof someInput&gt;”而不是“z.infer”。 (2认同)