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

如何使用toZod实现带字段重映射的Zod Schema类型校验?

解决Zod Transform后类型与toZod冲突的问题

问题根源在于:toZod<Country>对应的是ZodObject类型,但调用.transform()方法后,返回的是ZodEffects类型,二者类型不兼容,直接赋值会触发类型错误。

下面提供两种可行的解决方式:

方式一:移除变量类型注解,让Zod自动推导

直接去掉testZodObj的toZod<Country>注解,利用Zod自身的类型推导能力,同时用satisfies确保transform的返回值符合Country接口结构:

import { z } from "zod";
import type { toZod } from "zod-to-ts";

interface Country {
  isoCode: string;
  nameEn: string;
  nameDe: string;
  phone: string;
  bla: string;
}

const CountryJson = {
  isoCode: "DE",
  nameEn: "Germany",
  nameDe: "Deutschland",
  phone: "+49",
  blubb: "test123",
};

// 移除toZod<Country>注解,让Zod处理类型推导
const testZodObj = z
  .object({
    isoCode: z.string(),
    nameEn: z.string(),
    nameDe: z.string(),
    phone: z.string(),
    blubb: z.string(),
  })
  .transform((item) => {
    const { blubb: bla, ...rest } = item;
    // 用satisfies确保返回值符合Country接口
    return {
      ...rest,
      bla,
    } satisfies Country;
  });

// 可以直接用Country作为返回类型,或通过z.infer推导
function print(): Country {
  return testZodObj.parse(CountryJson);
}

const out = print();
console.log(out); // 输出: { isoCode: 'DE', nameEn: 'Germany', nameDe: 'Deutschland', phone: '+49', bla: 'test123' }

方式二:拆分输入输出schema,分别约束类型

如果需要明确约束API输入的结构,可以拆分出API响应和数据库存储两个接口,分别定义对应的Zod schema:

import { z } from "zod";
import type { toZod } from "zod-to-ts";

// 定义API返回的原始结构
interface CountryApiResponse {
  isoCode: string;
  nameEn: string;
  nameDe: string;
  phone: string;
  blubb: string;
}

// 数据库存储的目标结构
interface Country {
  isoCode: string;
  nameEn: string;
  nameDe: string;
  phone: string;
  bla: string;
}

const CountryJson: CountryApiResponse = {
  isoCode: "DE",
  nameEn: "Germany",
  nameDe: "Deutschland",
  phone: "+49",
  blubb: "test123",
};

// 用toZod约束API输入的schema类型
const countryApiSchema: toZod<CountryApiResponse> = z.object({
  isoCode: z.string(),
  nameEn: z.string(),
  nameDe: z.string(),
  phone: z.string(),
  blubb: z.string(),
});

// 基于输入schema做transform,得到数据库目标schema
const countryDbSchema = countryApiSchema.transform((item) => {
  const { blubb: bla, ...rest } = item;
  return {
    ...rest,
    bla,
  } satisfies Country;
});

function print(): Country {
  return countryDbSchema.parse(CountryJson);
}

const out = print();
console.log(out);

两种方式都能确保最终返回的类型完全匹配Country接口,同时避免Zod类型冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 15:37:33