我正在尝试编写一个解码器函数(
decode
),它接受 Zod 模式和 unknown
输入。如果 Zod 编解码器的输入和输出类型不同,它应该能够验证输入并转换它。
当我尝试这样做时:
import { ZodSchema, z } from 'zod'
const DateFromString = z.string().transform(input => new Date(input))
const Event = z.object({ timestamp: DateFromString })
const decode = <T>(schema: ZodSchema<T>, data: unknown): T => schema.parse(data)
const { timestamp } = decode(Event, { timestamp: '2024-01-01' })
我收到以下类型错误:
“_input.timestamp”的类型在这些类型之间不兼容。 类型“字符串”不可分配给类型“日期”。(2345)
有没有办法修复此类型错误并且确保最后一行的
timestamp
变量的类型为Date
?
问我问题的另一种方法是如何只定义一个
decode
函数,而不是仅仅为了输入而重复实现:
import { ZodArray, ZodObject, ZodRawShape, ZodUnion, ZodUnionOptions } from 'zod'
const decodeObject = <T extends ZodRawShape>(schema: ZodObject<T>, data: unknown) =>
schema.parse(data)
const decodeArray = <T extends ZodRawShape>(schema: ZodArray<ZodObject<T>>, data: unknown) =>
schema.parse(data)
const decodeUnion = <T extends ZodUnionOptions>(schema: ZodUnion<T>, data: unknown) =>
schema.parse(data)
错误字面上说明了一切,您正在尝试将 js Date 对象作为字符串放置。
“字符串”类型不可分配给“日期”类型。
所以你需要将日期转换为字符串。
import { ZodSchema, z } from 'zod'
const DateFromString = z.string().transform(input => new Date(input).toString()) // HERE
const Event = z.object({ timestamp: DateFromString })
const decode = <T>(schema: ZodSchema<T>, data: unknown): T => schema.parse(data)
const { timestamp } = decode(Event, { timestamp: '2024-01-01' })
但我明白了,你想要
Date
类型,对吗?所以使用zod.custom
:
import { ZodSchema, z } from 'zod';
const DateFromString = z.custom<Date>().transform((input) => new Date(input));
const Event = z.object({ timestamp: DateFromString });
const decode = <T>(schema: ZodSchema<T>, data: unknown): T =>
schema.parse(data);
const { timestamp } = decode(Event, { timestamp: '2024-01-01' });