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

如何在TypeScript中正确使用经Zod序列化后的对象类型?

解决Zod Transform导致TypeScript类型不匹配的问题

你遇到的核心问题是:Zod的transform(JSON.stringify)把booking字段的类型从预订项数组转换成了字符串,但你的build函数仍试图以原始数组元素的方式访问type属性,自然触发类型错误。以下是几种无需关闭类型检查的解决方案:


方案1:拆分Schema,区分原始类型与序列化后类型

把原始预订项的Schema单独提取,既保留业务处理所需的原始类型,又能得到序列化后的最终类型:

// 定义原始预订项的Schema与类型
const BookingItem = z.discriminatedUnion('type', [
  z.object({ type: z.literal('url'), input: z.string().url() }),
  z.object({ type: z.literal('email'), input: z.string().email() })
]);
type BookingItem = z.infer<typeof BookingItem>;
type BookingArray = BookingItem[];

// 定义最终的Event Schema,对booking做序列化转换
export const Event = z.object({
  // 其他字段...
  booking: z.array(BookingItem).transform(t => JSON.stringify(t))
});

export type Event = z.infer<typeof Event>;

修改build函数,让它接收原始的BookingArray类型:

export const build = (booking: BookingArray) => {
  const output: string[] = [];
  for (const b of booking) {
    if (b.type === 'url') output.push(`abc`);
    if (b.type === 'email') output.push(`xyz`);
  }
  return output;
};

方案2:若必须处理序列化后的字符串(不推荐)

如果build函数只能拿到已序列化的字符串(比如从后端返回的数据),需先解析回原始数组,并用Zod验证保证类型安全:

export const build = (bookingStrings: Event['booking'][]) => {
  const output: string[] = [];
  for (const str of bookingStrings) {
    // 用Zod解析并验证字符串转数组的结果
    const bookingItems = z.array(BookingItem).parse(JSON.parse(str));
    for (const b of bookingItems) {
      if (b.type === 'url') output.push(`abc`);
      if (b.type === 'email') output.push(`xyz`);
    }
  }
  return output;
};

方案3:调整序列化时机(业务允许时优先选)

如果不需要在Schema层面完成序列化,可把转换逻辑移到业务代码中,让Schema保留原始数组类型:

export const Event = z.object({
  // 其他字段...
  booking: z.array(
    z.discriminatedUnion('type', [
      z.object({ type: z.literal('url'), input: z.string().url() }),
      z.object({ type: z.literal('email'), input: z.string().email() })
    ])
  )
});

export type Event = z.infer<typeof Event>;

// 在需要序列化的场景手动转换
const parsedEvent = Event.parse(rawData);
const serializedBooking = JSON.stringify(parsedEvent.booking);

此时build函数直接使用Event['booking']类型即可正常访问type属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 18:45:30