如何使用Superstruct验证对象数组的唯一键约束?
用Superstruct验证对象数组指定键的唯一性
Superstruct本身没有内置的唯一性验证规则,但可以通过自定义refine规则实现数组内对象指定键的唯一性校验,以下是具体实现方案:
基础实现(指定固定键)
先导入Superstruct核心方法,定义基础对象结构,再通过refine扩展唯一性校验逻辑:
import { object, string, array, refine, assert } from 'superstruct'; // 定义单个对象的结构规则 const User = object({ id: string(), name: string(), }); // 创建带id唯一性校验的用户数组结构 const UniqueUserArray = refine( array(User), 'UniqueUserArray', (users) => { const ids = users.map(user => user.id); // 通过Set去重后对比长度,判断是否存在重复id return new Set(ids).size === ids.length; }, '数组中所有对象的id必须唯一' );
验证示例
- 合法数据(无重复id):
const validUsers = [ { id: 'user_001', name: 'Alice' }, { id: 'user_002', name: 'Bob' }, ]; assert(validUsers, UniqueUserArray); // 无错误抛出
- 非法数据(存在重复id):
const invalidUsers = [ { id: 'user_001', name: 'Alice' }, { id: 'user_001', name: 'Charlie' }, ]; assert(invalidUsers, UniqueUserArray); // 抛出错误,提示"数组中所有对象的id必须唯一"
通用化实现(支持任意指定键)
如果需要校验不同的对象键,可以封装通用函数避免重复代码:
import { array, refine, Struct } from 'superstruct'; /** * 创建带指定键唯一性校验的数组结构 * @param struct - 单个对象的结构定义 * @param key - 需要校验唯一性的对象键名 * @returns 带唯一性校验的数组结构 */ function createUniqueArrayStruct<T>(struct: Struct<T>, key: keyof T) { return refine( array(struct), `UniqueArray<${struct.type.name}, ${String(key)}>`, (items) => { const valueMap = new Map(); for (const item of items) { const value = item[key]; if (valueMap.has(value)) { // 抛出具体重复值,方便定位问题 throw new Error(`发现重复的${String(key)}值: ${value}`); } valueMap.set(value, true); } return true; } ); } // 使用示例 const UniqueUserArrayById = createUniqueArrayStruct(User, 'id'); // 假设User结构包含email字段,可直接复用函数校验email唯一性 const UniqueUserArrayByEmail = createUniqueArrayStruct(User, 'email');
注意事项
- 如果对象的指定键可能为
undefined或null,可在校验逻辑中添加判断,比如过滤空值后再检查,或根据业务需求决定是否允许空值重复 - 自定义错误时抛出具体重复值,能大幅提升调试效率,避免模糊的错误提示
内容的提问来源于stack exchange,提问作者yo_nas
相关产品推荐
相关产品推荐

