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

如何在Zod共享类型文件中实现前后端字段差异化验证?

实现前后端共享类型的选择性验证

要在同一类型文件中让_id字段在后端作为ObjectId验证、前端作为String验证,可以通过环境条件判断结合Zod的schema实现,具体方案如下:

核心思路

利用前后端运行环境的差异(Node.js vs 浏览器),通过条件分支选择对应的Zod验证规则,同时保证类型推断自动适配两端需求。

具体实现

1. 基于环境变量的条件判断

修改现有代码,添加环境分支逻辑:

import { z } from "zod";
import { ObjectId } from "bson";

// 根据环境选择对应的ID验证规则
const idValidationSchema = typeof process !== "undefined" && process.env.IS_SERVER === "true"
  // 后端:验证并转换为ObjectId
  ? z.custom<ObjectId>().transform((value) => new ObjectId(value))
  // 前端:验证为字符串
  : z.string();

// 定义BaseObject schema
export const BaseObject = z.object({
  _id: idValidationSchema.optional(),
});

// 导出自动推断的类型
export type BaseObject = z.infer<typeof BaseObject>;

2. 配置环境变量(可选优化)

为了更精准区分前后端,可通过构建工具注入环境变量:

  • 后端Node环境:在启动脚本中设置IS_SERVER=true(比如cross-env IS_SERVER=true node server.js)
  • 前端构建工具(如Vite/Webpack):注入IS_SERVER=false的全局变量,简化判断逻辑

以Vite为例,在vite.config.js中添加:

export default {
  define: {
    IS_SERVER: JSON.stringify(false),
  },
};

此时代码可简化为:

const idValidationSchema = IS_SERVER
  ? z.custom<ObjectId>().transform((value) => new ObjectId(value))
  : z.string();

效果说明

  • 后端环境:_id字段会被验证为合法的ObjectId格式,并转换为ObjectId实例,类型推断结果为ObjectId | undefined
  • 前端环境:_id字段仅需符合字符串格式,类型推断结果为string | undefined
  • 前端无需额外处理bson包,构建工具会自动tree-shaking掉未使用的ObjectId相关代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:52:39