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

如何实现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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 20:48:03