typescript 使用非可选但可能未定义的字段指定Zod方案

6mw9ycah  于 2022-12-05  发布在  TypeScript
关注(0)|答案(2)|浏览(140)

是否可以使用可能为undefined但非可选的字段来定义Zod架构。在TypeScript中,这是以下两者之间的区别:

interface IFoo1 {
  somefield: string | undefined;
}

interface IFoo2 {
  somefield?: string | undefined;
}

const schema = z.object({
  somefield: z.union([z.string(), z.undefined()]),
}); // Results in something like IFoo1

据我所知,使用z.union([z.string(), z.undefined()])z.string().optional()会导致字段等效于IFoo2
我想知道是否有一种方法可以指定一个行为类似IFoo1的模式。

上下文/理由

我之所以要这样做,是为了迫使开发人员考虑字段是否应该是undefined。当字段是可选的时,在构造该类型的对象时可能会意外地遗漏它。一个具体的例子可能如下所示:

interface IConfig {
  name: string;
  emailPreference: boolean | undefined;
}
enum EmailSetting {
  ALL,
  CORE_ONLY,
}

function internal(config: IConfig) {
  return {
    name: config.name,
    marketingEmail: config.emailPreference ? EmailSetting.ALL : EmailSetting.CORE_ONLY,
  }
}

export function signup(userName: string) {
  post(internal({ name: userName }));
}

这是一个人为的例子,但在我们的代码库中,React属性经常出现这种情况。在示例中,我希望在调用internal时出现错误,因为我希望调用者考虑电子邮件首选项。理想情况下,这里的类型错误会使我意识到我应该将电子邮件首选项作为signup的参数。

edqdpe6u

edqdpe6u1#

您可以使用transform函数显式设置感兴趣的字段。这有点麻烦,但很有效。

const schema = z
    .object({
        somefield: z.string().optional(),
    })
    .transform((o) => ({ somefield: o.somefield }));

type IFoo1 = z.infer<typeof schema>;
// is equal to { somefield: string | undefined }
xdnvmnnf

xdnvmnnf2#

根据以下文档,z.optional()似乎是您要查找的内容:https://github.com/colinhacks/zod#optionals

const schema = z.optional(z.string());

schema.parse(undefined); // => returns undefined
type A = z.infer<typeof schema>; // string | undefined

相关问题