我想解析依赖于基类型的不同模式的数组:

// Simple example
const typeA = z.object({ prop: z.string() });

const typeB = typeA.extend({
  extraProp: z.boolean(),
});

我try 了以下模式:

const schema = z.array(z.union([typeA, typeB]));

问题是当我解析数据时,typeB项被解析为type A,所以extraProp从输出中删除

const data = schema.parse([{ prop: 'foo', extraProp: true }]);
// => [{"prop":"foo"}]

当我将typeB作为联合的第一项时,它似乎输出了正确的类型,但当发送错误的数据时,它被解析为typeA:

const schema = z.array(z.union([typeB, typeA]));

const data = schema.parse([{ prop: 'foo', extraProp: true }]);
// => [{"prop":"foo","extraProp":true}]

...

const data = schema.parse([{ prop: 'foo', extraProp: 4 }]);
// => [{"prop":"foo"}] - should fail here

是我的模式错了,还是Zod做不到呢?

推荐答案

摘自Zod的Unions部分(增加了重点):

Zod将按照顺序测试每个"选项"的输入,并返回成功验证的the first value.

没有更多也没有更少:它在z.union([typeA, typeB])分钟内try typeA,如果它验证了,则返回解析的数据,否则,它将 试试typeB,以此类推.

人们倾向于认为它计算某种形式的联合对象模式, 但它没有.这就解释了为什么最后一个例子是有效的:typeB失败, 然后它只解析typeA,就像没有typeB一样.

人们有理由期待这一点--例如,它不会在 Typescript :

type A = {prop: string};
type B = A & {extraProp: boolean};
type Sch = B | A;

const o: Sch = { prop: 'foo', extraProp: 2 }; 
// error TS2322: type 'number' is not assignable to type 'boolean' 

在这两种情况下都能模拟预期行为的构造是 一百:

const typeA = z.object({ prop: z.string() });
const typeB = typeA.extend({
   extraProp: z.boolean(),
});

const schema = z.array(typeB.merge(typeA));
const data = schema.parse([{ prop: 'foo', extraProp: 2 }]);
//{prop: 'foo', extraProp: true}
// ......
const schemaBA = z.array(typeB.merge(typeA));
schemaBA.parse([{ prop: 'foo', extraProp: 2 }]);

//Uncaught ZodError: [{
//  //......
//  "message": "Expected boolean, received number"
// }]

Javascript相关问答推荐

如何按预期聚合SON数据?

如何通过onClick为一组按钮分配功能;

具有相同参数的JS类

使用axios.获取实时服务器时的404响应

如何才能拥有在jQuery终端中执行命令的链接?

如何在Angular17 APP中全局设置AXIOS

在运行时使用Next JS App Router在服务器组件中运行自定义函数

使用NextJS+MongoDB+Prisma ORM获取无效请求正文,无法发布错误

如何使用基于promise (非事件emits 器)的方法来传输数据?

当代码另有说明时,随机放置的圆圈有时会从画布上消失

未捕获的运行时错误:调度程序为空

无法读取未定义的属性(正在读取合并)-react RTK

MongoDB中的嵌套搜索

如何在Jest中模拟函数

未找到用于 Select 器的元素:in( puppeteer 师错误)

需要RTK-在ReactJS中查询多个组件的Mutations 数据

如何设置时间选取器的起始值,仅当它获得焦点时?

输入数据覆盖JSON文件

不允许在对象文本中注释掉的属性

如何在不将整个文件加载到内存的情况下,在Node.js中实现Unix粘贴命令?