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

使用Zod编写decode函数时的类型错误及通用实现问询

问题与解决方案

问题描述

我尝试编写一个decode函数,接收Zod schema与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' })

出现类型错误:

The types of '_input.timestamp' are incompatible between these types.
Type 'string' is not assignable to type 'Date'.(2345)

需求是修复该类型错误,同时确保最后一行的timestamp变量为Date类型;另外希望仅定义一个通用的decode函数,而非为不同类型的schema(如Object、Array、Union)重复实现多个函数(如下示例):

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)

解决方案

通用decode函数的正确实现

问题出在原函数的泛型定义上:ZodSchema<T>仅指定了schema的输出类型,TypeScript会错误地要求输入data匹配输出类型,而非schema实际接受的输入类型。

改用基于schema本身的泛型,并通过Zod内置的z.infer<S>获取输出类型,即可解决问题:

import { ZodType, z } from 'zod'

const DateFromString = z.string().transform(input => new Date(input))

const Event = z.object({ timestamp: DateFromString })

// 通用decode函数,支持所有Zod schema类型
const decode = <S extends ZodType>(schema: S, data: unknown): z.infer<S> => {
  return schema.parse(data)
}

// 调用示例:无类型错误,timestamp类型为Date
const { timestamp } = decode(Event, { timestamp: '2024-01-01' })

原理说明

  • 泛型S extends ZodType:涵盖所有Zod schema类型(Object、Array、Union等),无需为不同schema类型单独实现函数
  • z.infer<S>:自动推导schema的输出类型,确保返回值类型正确
  • 输入data指定为unknown:符合Zodparse方法的参数要求,同时避免TypeScript错误地将输入与输出类型做强制匹配

这样既解决了类型错误,又实现了单一通用函数的需求,同时保证timestamp最终为Date类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:35:16