Lzh on GitHub

交叉(intersection)代表一种逻辑“与”的关系。你可以使用 intersect 模式函数或者通过将多个对象模式合并为一个新模式来应用此概念。我们建议对简单的对象模式采用后者,而对所有其他情况使用 intersect

intersect 模式

intersect 模式函数在你以数组形式传入的任意数量的模式之间创建“与”的关系。要通过验证,传入的每个模式的验证都必须成功。如果成功,该模式将合并各个模式的输出并返回结果。如果验证失败,该模式会返回所有发生的问题。

import * as v from 'valibot';

// TypeScript
type Intersect = { foo: string } & { bar: number };

// Valibot
const IntersectSchema = v.intersect([
  v.object({ foo: v.string() }),
  v.object({ bar: v.number() }),
]);

合并对象

从技术上讲,intersect 和对象合并有很大的区别。intersect 是一个在验证过程中执行所传入模式的模式函数。相比之下,对象合并是在初始化时完成的,用于创建一个新的对象模式。

因此,在验证未知数据时,对象合并通常比 intersect 具有更好的性能。此外,后续的对象属性会覆盖先前的属性。而 intersect 则不会出现这种情况,因为如果两个同名属性从根本上不同,验证就会失败。

import * as v from 'valibot';

const ObjectSchema1 = v.object({ foo: v.string(), baz: v.number() });
const ObjectSchema2 = v.object({ bar: v.string(), baz: v.boolean() });

const MergedSchema = v.object({
  ...ObjectSchema1.entries,
  ...ObjectSchema2.entries,
}); // { foo: string; bar: string; baz: boolean }

在上面的代码示例中,第一个对象模式的 baz 属性被第二个对象模式的 baz 属性覆盖了。