如何实现Typescript泛型函数检测数组与现有状态的重复项
实现方案
版本1:固定按name字段查重(匹配你预期的函数签名)
如果你的所有使用场景都是按name字段判断重复,可以给泛型增加约束,强制元素必须包含name属性,类型完全符合TS规范:
export const checkDuplicate = <T extends { name: string }>(items: T[], existingState: T[]): void => { // 检测items内部重复 const itemNameSet = new Set(items.map(item => item.name)); if (itemNameSet.size !== items.length) { throw new Error('contains identical information'); } // 检测items和现有状态的重复 const existingNameSet = new Set(existingState.map(item => item.name)); for (const item of items) { if (existingNameSet.has(item.name)) { throw new Error('contains identical information'); } } };
调用方式和你原来的代码完全一致:
checkDuplicate(students, existingState);
版本2:通用泛型版本(支持指定任意字段查重)
如果需要兼容不同结构的数组元素,可以增加第三个参数指定查重的字段名,适用场景更广,类型安全:
export const checkDuplicate = <T>(items: T[], existingState: T[], duplicateKey: keyof T): void => { // 检测items内部重复 const itemKeySet = new Set(); for (const item of items) { const currentKey = item[duplicateKey]; if (itemKeySet.has(currentKey)) { throw new Error('contains identical information'); } itemKeySet.add(currentKey); } // 检测items和现有状态的重复 const existingKeySet = new Set(existingState.map(item => item[duplicateKey])); for (const item of items) { if (existingKeySet.has(item[duplicateKey])) { throw new Error('contains identical information'); } } };
调用时传入要查重的字段即可:
// 按name字段查重 checkDuplicate(students, existingState, 'name'); // 如果后续需要按class字段查重,直接改参数即可,TS会自动校验字段合法性 checkDuplicate(students, existingState, 'class');
扩展:多字段联合查重
如果需要多个字段同时匹配才判定为重复,可以调整为传入字段数组:
export const checkDuplicateByMultiKeys = <T>(items: T[], existingState: T[], duplicateKeys: Array<keyof T>): void => { const getCombineKey = (item: T) => duplicateKeys.map(key => item[key]).join('||'); const itemKeySet = new Set(); for (const item of items) { const key = getCombineKey(item); if (itemKeySet.has(key)) throw new Error('contains identical information'); itemKeySet.add(key); } const existingKeySet = new Set(existingState.map(getCombineKey)); for (const item of items) { if (existingKeySet.has(getCombineKey(item))) throw new Error('contains identical information'); } }; // 调用示例:name和class都相同才判定为重复 checkDuplicateByMultiKeys(students, existingState, ['name', 'class']);
内容的提问来源于stack exchange,提问作者ffx292
相关产品推荐
相关产品推荐

