You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于已有对象创建Zod枚举并生成TypeScript联合类型

问题描述

我有如下对象数组:

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;

需要结合Zod实现两个目标:

  • 在后端验证并解析数据
  • 生成对应的TypeScript联合类型 "entire_place" | "shared_room" | "private_room"

按照Zod文档的常规写法需要重复定义值数组,但我不想重复维护数据(一次带label用于UI展示,一次仅保留value用于验证和类型),希望仅通过properties对象完成Zod枚举创建和类型推断,求可行方案?

解决方案

可以利用TypeScript的类型推断能力和Zod的API,直接从properties数组中提取所需的value常量值,无需重复定义:

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;

// 提取所有value字段的常量值数组
const propertyValues = properties.map(item => item.value) as readonly (typeof properties[number]["value"])[];

// 创建用于验证的Zod枚举 schema
const PropertySchema = z.enum(propertyValues);

// 自动推断对应的TypeScript联合类型
type Property = z.infer<typeof PropertySchema>;

关键细节说明

  • as const修饰符让TypeScript将properties推断为只读常量数组,保留每个value的字面量类型(而非宽泛的string类型)
  • typeof properties[number]["value"]会自动提取数组中所有对象的value字段类型,生成联合类型 "entire_place" | "private_room" | "shared_room"
  • 对map结果添加类型断言是因为TypeScript默认不会将map返回的数组推断为常量数组,这个断言能让Zod正确识别为合法的枚举值集合
  • 最终PropertySchema可直接用于后端验证输入数据,Property类型则能在业务代码中提供类型约束

内容的提问来源于stack exchange,提问作者user19910212

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:15:31