遇到一个奇怪的问题:在参数内创建数组可以进行传入到z.enum(),但是在参数外创建的不能进行传入?

遇到一个奇怪的问题:在参数内创建数组可以进行传入到z.enum(),但是在参数外创建的不能进行传入:

import * as z from 'zod';

const WINDOW_EVENTS2 = [
  'EVENT_UPDATE_DATA',
  'EVENT_REARRANGE'
]

const windowEventsSchema = z.enum(WINDOW_EVENTS2);  // 会报错:没有与此调用匹配的重载

这样就可以:

const Schema = z.enum(['EVENT_UPDATE_DATA', 'EVENT_REARRANGE']);

报错信息:

没有与此调用匹配的重载。
  第 1 个重载(共 2 个),“(values: readonly [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>”,出现以下错误。
    类型“string[]”的参数不能赋给类型“readonly [string, ...string[]]”的参数。
      源不提供目标中位置 0 处所需元素的匹配项。
  第 2 个重载(共 2 个),“(values: [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>”,出现以下错误。
    类型“string[]”的参数不能赋给类型“[string, ...string[]]”的参数。
      源不提供目标中位置 0 处所需元素的匹配项。ts(2769)
阅读 511
avatarAI BotBETA
### 回答

这个问题是由于 TypeScript 中数组字面量和数组变量的类型推断差异导致的。在 Zod 库中,`z.enum()` 方法期望一个具体的数组字面量(即直接在函数调用中定义的数组),而不是一个通过变量引用的数组。

当你使用数组字面量时,如 `z.enum(['EVENT_UPDATE_DATA', 'EVENT_REARRANGE'])`,TypeScript 能够准确地推断这是一个固定长度的元组类型(tuple type),其中的每个元素都是字符串,且数组的长度和元素都是已知的。

然而,当你将数组赋值给一个变量(如 `WINDOW_EVENTS2`),然后将其传递给 `z.enum()` 时,TypeScript 将这个变量推断为一个普通的数组类型 `string[]`,即一个包含任意数量字符串的数组。这与 `z.enum()` 所期望的具体元组类型不匹配,因此会导致类型错误。

为了解决这个问题,你可以确保传递给 `z.enum()` 的是一个元组类型,而不是一个普通的数组。这可以通过使用 `as const` 断言来实现,它可以将数组字面量转换为一个只读元组:

const WINDOW_EVENTS2 = ['EVENT_UPDATE_DATA', 'EVENT_REARRANGE'] as const;
const windowEventsSchema = z.enum(WINDOW_EVENTS2);


使用 `as const` 后,`WINDOW_EVENTS2` 将被推断为一个具体的元组类型,而不是一个普通的数组类型,这样就可以与 `z.enum()` 的期望匹配了。
1 个回答

定义时候添加:as const即可:

const WINDOW_EVENTS2 = ['EVENT_UPDATE_DATA', 'EVENT_REARRANGE'] as const;
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏