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

如何基于as const定义的对象创建Zod枚举类型?

问题:基于已有const对象创建Zod枚举类型

我有一个自动生成的对象:

export const ReportDimensions = {
  CHANNELS: 'CHANNELS',
  DAY: 'DAY',
  DOW: 'DOW',
  MONTH: 'MONTH',
  WEEK: 'WEEK'
} as const;

我希望使用Zod创建仅允许该对象值的枚举,即允许["MONTH","WEEK","DOW", "DAY", "CHANNELS"]这些值。尝试使用z.enum(Object.keys(ReportDimensions))时出现如下报错:

No overload matches this call.
Overload 1 of 2, '(values: readonly [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>', gave the following error.
Argument of type 'string[]' is not assignable to parameter of type 'readonly [string, ...string[]]'.
Source provides no match for required element at position 0 in target.
Overload 2 of 2, '(values: [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>', gave the following error.
Argument of type 'string[]' is not assignable to parameter of type '[string, ...string[]]'.
Source provides no match for required element at position 0 in target.ts(2769)


原因分析

Object.keys()返回的类型是string[],而Zod的z.enum()要求传入非空的只读字符串字面量数组类型(readonly [string, ...string[]])。TypeScript无法推断Object.keys()的结果是确定的非空数组,也无法保留具体的字符串字面量类型,因此触发类型报错。

正确实现方式

你的对象已经使用as const锁定了字面量类型,可以通过以下两种方式实现需求:

方式一:提取对象值并断言为字面量数组

import { z } from "zod";

export const ReportDimensions = {
  CHANNELS: 'CHANNELS',
  DAY: 'DAY',
  DOW: 'DOW',
  MONTH: 'MONTH',
  WEEK: 'WEEK'
} as const;

// 提取对象值并断言为字面量数组
const dimensionValues = Object.values(ReportDimensions) as [typeof ReportDimensions[keyof typeof ReportDimensions]];

// 创建Zod枚举
const ReportDimensionSchema = z.enum(dimensionValues);

// 导出对应的TypeScript类型
type ReportDimension = z.infer<typeof ReportDimensionSchema>;

方式二:使用z.nativeEnum(更简洁)

由于你的对象键值完全一致,直接使用z.nativeEnum可以自动解析常量对象的键值作为枚举选项:

import { z } from "zod";

export const ReportDimensions = {
  CHANNELS: 'CHANNELS',
  DAY: 'DAY',
  DOW: 'DOW',
  MONTH: 'MONTH',
  WEEK: 'WEEK'
} as const;

// 创建Zod枚举
const ReportDimensionSchema = z.nativeEnum(ReportDimensions);

// 导出对应的TypeScript类型
type ReportDimension = z.infer<typeof ReportDimensionSchema>;

验证效果

两种方式都能严格限制枚举值范围:

  • 合法值:ReportDimensionSchema.parse("MONTH") → 解析成功
  • 非法值:ReportDimensionSchema.parse("YEAR") → 抛出Zod验证错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:01:43