typescript Zod nativeEnum类型检查枚举的值

h5qlskok  于 2023-08-08  发布在  TypeScript
关注(0)|答案(1)|浏览(99)

我正在使用zod模式来验证一个带有枚举字段的对象:

enum Colour {
    red: 'Red',
    blue: 'Blue',
}

const schema = z.object({
    colour: z.nativeEnum(Colour),
});

字符串
我有来自API的输入数据,颜色值是'red'或'blue',我想用上面的模式检查一下。然而,上面的schema的nativeEnum根据enum中的大写大小写进行检查,而不是enum属性:

enum Colour {
    red: 'Red',
    blue: 'Blue',
}

const schema = z.object({
    colour: z.nativeEnum(Colour),
});

const rawInput1 = {
    colour: 'red' // should be identified as valid
};
const parsedInput1 = schema.parse(rawInput1); // this fails

const rawInput2 = {
    colour: 'Red' // should be identified as invalid
};
const parsedInput2 = schema.parse(rawInput2); // this passes


我怎样才能让zod基于枚举中的属性而不是值进行验证?为什么会这样?
我之所以还想解析枚举属性,并以这种方式定义枚举,是因为我想解析对象,并使用colour变量在枚举中索引其字符串值:Colour[parsedInput1.colour]。如果colour是字符串值,则不可能这样做。

webghufk

webghufk1#

您可以使用常规的.enum()并使用Object.keys()提取枚举键来验证它:

enum Colour {
    red = 'Red',
    blue = 'Blue',
}

const keys = Object.keys(Colours) // ["red", "blue"]

const schema = z.object({
    colour: z.enum(keys),
});

字符串
但问题是,这里的keys类型是string[],而不是["red", "blue"](即使这将是运行时的实际值)。所以它会工作,但你不会得到类型脚本验证...
使用keyof typeof可以获得枚举键的联合

type KeyUnion = keyof typeof Colour // "red" | "blue"


因此,通过一点“对类型脚本撒谎”,我们可以通过转换keys类型来实现所需的结果:

const keys = Object.keys(Colours) as [keyof typeof Colour]
const schema = z.object({
    colour: z.enum(keys),
});


这将使您获得在类型级别和运行时都有效的东西。
但是请注意,keys实际上不是[keyof typeof Colour]类型,这只是我们为了获得正确的推断而对typescript说的一个谎言。

相关问题