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

如何用Zod实现类似TypeScript多接口继承的优雅方案?

使用Zod实现类似TypeScript多接口继承的复合类型

在TypeScript中我们可以通过多接口继承定义复合类型,就像这样:

interface Name {
  name: string
}

interface Age {
  age: number
}

interface People extends Name, Age {
  height: number
}

要在Zod中实现同样的效果,除了链式调用merge的写法,还有几种更简洁易读的方案:

方案1:利用shape属性+对象展开语法

每个Zod对象Schema都自带shape属性,包含其定义的所有字段规则。我们可以直接将多个基础Schema的shape展开到新的对象Schema中,写法和TS接口继承的逻辑高度一致:

import { z } from "zod";

const nameZ = z.object({ name: z.string() });
const ageZ = z.object({ age: z.number() });

const peopleZ = z.object({
  height: z.number(),
  ...nameZ.shape,
  ...ageZ.shape,
});

这种方式把所有字段规则集中在一起,结构清晰,一眼就能看出peopleZ包含哪些字段。

方案2:先合并基础Schema再扩展新字段

使用Zod的merge先组合基础的类型Schema,再用extend添加新字段,逻辑顺序和TS接口继承完全对应:

import { z } from "zod";

const nameZ = z.object({ name: z.string() });
const ageZ = z.object({ age: z.number() });

const peopleZ = nameZ.merge(ageZ).extend({ height: z.number() });

先合并nameZ和ageZ得到基础的人员属性,再扩展height字段,可读性比多次链式merge更好。

方案3:使用z.intersection(适合强调类型交叉场景)

如果需要明确表达“同时满足多个Schema约束”的复合类型,可以用z.intersection来组合多个对象Schema:

import { z } from "zod";

const nameZ = z.object({ name: z.string() });
const ageZ = z.object({ age: z.number() });
const heightZ = z.object({ height: z.number() });

const peopleZ = z.intersection(z.intersection(nameZ, ageZ), heightZ);

这种写法更偏向“类型交叉”的语义,适合复杂的类型组合场景,不过对于简单的对象字段合并来说,前两种方案更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:22:37