从对象创建 zod 枚举

19 validation types object typescript zod

我有这个对象

const properties = [
  { value: "entire_place", label: "The entire place" },
  { value: "private_room", label: "A private room" },
  { value: "shared_room", label: "A shared room" },
] as const;
Run Code Online (Sandbox Code Playgroud)

我需要将它与 zod 一起使用才能

  1. 在后端验证并解析我的数据
  2. 使用这些可能的值创建打字稿联合类型"entire_place" | "shared_room" | "private_room"

根据zod 文档,我可以这样做:

const properties = [
  { value: "entire_place", label: "The entire place" },
  { value: "private_room", label: "A private room" },
  { value: "shared_room", label: "A shared room" },
] as const;

const VALUES = ["entire_place", "private_room", "shared_room"] as const;
const Property = z.enum(VALUES);
type Property = z.infer<typeof Property>;
Run Code Online (Sandbox Code Playgroud)

但是,我不想两次定义我的数据,一次带有标签(标签用于 ui 目的),另一次没有标签

我只想使用properties对象而不使用VALUES数组来定义它一次,并使用它来创建 zod 对象并从 zod 对象推断类型。

有什么办法解决吗?

Sou*_*man 20

Property在这种情况下,我想我会直接推断出from的类型properties。您可以避免重复使用如下代码:

import { z } from "zod";

const properties = [
  { value: "entire_place", label: "The entire place" },
  { value: "private_room", label: "A private room" },
  { value: "shared_room", label: "A shared room" }
] as const;

type Property = typeof properties[number]["value"];
// z.enum expects a non-empty array so to work around that
// we pull the first value out explicitly
const VALUES: [Property, ...Property[]] = [
  properties[0].value,
  // And then merge in the remaining values from `properties`
  ...properties.slice(1).map((p) => p.value)
];
const Property = z.enum(VALUES);
Run Code Online (Sandbox Code Playgroud)