首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Zod:根据默认值创建一个原始对象

Zod:根据默认值创建一个原始对象
EN

Stack Overflow用户
提问于 2022-06-27 07:09:33
回答 2查看 528关注 0票数 2

我很确定这是存在的,但我没有找到关于它的任何东西,尽管我做了一些调查。假设我有这样一个zod模式:

代码语言:javascript
复制
const Person = zod.object({
    name: z.string().default(''),
    age: z.number().nullable();
});

有没有办法创造出这样的东西:

代码语言:javascript
复制
const InstancePerson = {
    name: '',
    age: null
}

zod模式?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-09 14:40:49

我知道我参加聚会有点晚了,但也许这会对将来的人有所帮助。

您可以通过以下方式扩展您的zod模式:

代码语言:javascript
复制
const Person = zod.object({
    name: z.string().default(''),
    age: z.number().nullable().default(null)
}).default({}); // .default({}) could be omitted in this case but should be set in nested objects

现在,您可以通过调用:

代码语言:javascript
复制
const InstancePerson = Person.parse({});
票数 1
EN

Stack Overflow用户

发布于 2022-06-30 12:27:09

似乎没有一种从库中直接完成这类事情的方法,但是您可以深入了解它们的_私有字段,并获得您想要的功能。

这种方法存在一些风险,因为库维护人员通常不能保证这些私有属性的稳定性。如果您依赖于这种行为,您可能需要格外小心版本的颠簸。

好的免责声明的方式,这样的事情是可能的。将其扩展到更多类型是读者的一项练习:

代码语言:javascript
复制
import { z } from "zod";

const schema = z.object({
  name: z.string(),
  age: z.number().nullable()
});

const schemaDefaults = <Schema extends z.ZodFirstPartySchemaTypes>(
  schema: Schema
): z.TypeOf<Schema> => {
  switch (schema._def.typeName) {
    case z.ZodFirstPartyTypeKind.ZodDefault:
      return schema._def.defaultValue();
    case z.ZodFirstPartyTypeKind.ZodObject: {
      // The switch wasn't able to infer this but the cast should
      // be safe.
      return Object.fromEntries(
        Object.entries(
          (schema as z.SomeZodObject).shape
        ).map(([key, value]) => [key, schemaDefaults(value)])
      );
    }
    case z.ZodFirstPartyTypeKind.ZodString:
      return "";
    case z.ZodFirstPartyTypeKind.ZodNull:
      return null;
    case z.ZodFirstPartyTypeKind.ZodNullable:
      return null;
    // etc
    default:
      throw new Error(`Unsupported type ${schema._type}`);
  }
};

console.log(schemaDefaults(schema));

在这里,我没有指定默认值,但是代码仍然输出您预期的结果。如果您将"foo“指定为name的默认值,则代码将输出{ name: "foo", age: null }

一种较短的方法是简单地在模式的_def中挖掘一个层,寻找要调用的defaultValue函数,但我认为给定的方法更有原则,因为它可以扩展到支持每一个核心zod模式类型。

最后一个警告词是,有些zod类型并不像其他类型那么简单。可以合理地给出类似z.number的缺省值0,但是z.unionz.intersection会有有趣的递归情况。

这可能是值得建立一个库,只是为了这种处理,否则打开一个问题与回购,使其成为提供的api的一部分。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72768172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档