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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:25:15