如何用Zod将API返回对象的数字状态转为衍生属性
使用Zod为API返回对象添加衍生属性
问题场景
API返回的原始对象结构如下:
{ id: '203923', name: 'best name', status: 1, }
需要通过Zod校验后,为对象添加前端UI所需的衍生属性statusLabel,最终得到的对象结构如下:
{ id: '203923', name: 'best name', status: 1, statusLabel: 'OK', }
原代码的问题
你之前的实现存在三个关键错误:
- 错误定义衍生字段:在schema中把
statusLabel声明为必填的z.string(),但API返回的原始对象中不存在这个字段,会导致Zod校验直接失败。 - transform使用位置错误:你给
statusLabel字段添加transform,但该字段本身不存在,无法获取值进行转换。正确的做法是对整个校验后的对象进行转换,基于已有的status字段生成statusLabel。 - 状态映射逻辑错误:switch中的case与返回的标签不匹配,比如
status=1(对应ReportMessageStatus.OK)却返回"DELETED",逻辑完全颠倒。
正确实现方案
步骤1:定义状态枚举
export enum ReportMessageStatus { UNKNOWN = 0, OK = 1, UNREAD, // 自动赋值为2 DELETED, // 自动赋值为3 }
步骤2:定义基础校验Schema
先定义对应API返回结构的基础Schema,只校验存在的字段:
import { z } from "zod"; const BaseReportMessageSchema = z.object({ id: z.string(), name: z.string(), status: z.nativeEnum(ReportMessageStatus), });
步骤3:通过transform添加衍生属性
对整个基础Schema的校验结果进行转换,添加statusLabel字段:
// 定义状态映射函数 function getStatusLabel(status: ReportMessageStatus): string { switch (status) { case ReportMessageStatus.OK: return "OK"; case ReportMessageStatus.UNREAD: return "UNREAD"; case ReportMessageStatus.DELETED: return "DELETED"; default: return "UNKNOWN"; } } // 生成最终的Schema export const ReportMessageSchema = BaseReportMessageSchema.transform((obj) => ({ ...obj, statusLabel: getStatusLabel(obj.status), }));
使用示例
// 模拟API返回数据 const apiData = { id: '203923', name: 'best name', status: 1, }; // 校验并转换数据 const result = ReportMessageSchema.parse(apiData); console.log(result); // 输出: // { // id: '203923', // name: 'best name', // status: 1, // statusLabel: 'OK', // }
内容的提问来源于stack exchange,提问作者MaylorTaylor
相关产品推荐
相关产品推荐

