如何使用Zod定义date类型并支持ISO日期字符串解析?
解决Zod中Date类型序列化/反序列化的校验问题
核心问题在于:JSON序列化时会将Date对象转为ISO格式字符串,反序列化后得到的是字符串而非Date实例,但z.date()仅校验Date对象,导致校验失败。下面提供两种实用方案:
方案1:使用z.preprocess预处理输入
先将字符串转换为Date对象,再进行有效性校验:
import { z } from "zod" const someTypeSchema = z.object({ t: z.preprocess( // 预处理:字符串转Date,非字符串直接保留 (val) => typeof val === "string" ? new Date(val) : val, // 校验并确保是有效Date(避免无效字符串转成Invalid Date) z.date().refine(date => !isNaN(date.getTime()), "Invalid date") ), }) type SomeType = z.infer<typeof someTypeSchema> function main() { const obj1: SomeType = { t: new Date(), } const stringified = JSON.stringify(obj1) console.log(stringified) const parsed = JSON.parse(stringified) const validated = someTypeSchema.parse(parsed) // 校验成功 console.log(validated.t instanceof Date) // 输出 true } main()
方案2:用union结合transform精准处理ISO字符串
如果明确输入是标准ISO 8601格式字符串,可采用这种更严谨的方式:
import { z } from "zod" const someTypeSchema = z.object({ t: z.union([ z.date(), // 直接接受原始Date对象 z.string().datetime().transform(str => new Date(str)) // 接受ISO字符串并转为Date ]), }) type SomeType = z.infer<typeof someTypeSchema> function main() { const obj1: SomeType = { t: new Date(), } const stringified = JSON.stringify(obj1) console.log(stringified) const parsed = JSON.parse(stringified) const validated = someTypeSchema.parse(parsed) // 校验成功 console.log(validated.t instanceof Date) // 输出 true } main()
z.string().datetime()会严格校验字符串是否符合ISO 8601格式(如YYYY-MM-DDTHH:mm:ss.sssZ),若需支持更多日期格式,可替换为z.string().refine(str => !isNaN(new Date(str).getTime()), "Invalid date")。
内容的提问来源于stack exchange,提问作者birgersp
相关产品推荐
相关产品推荐

