typescript数组去重泛型函数分三类:基础版用set处理原始类型;通用版通过comparefn支持任意类型;进阶版按对象属性key去重。均需泛型约束确保类型安全。

在 TypeScript 中定义数组去重的泛型函数,核心是让函数能接收任意类型的数组,并返回同类型(但去重后)的新数组。关键在于用泛型参数 T 约束元素类型,并确保去重逻辑不依赖具体类型细节(如只用 === 或 Object.is 比较原始值,或支持传入比较函数处理对象)。
基础版:适用于原始类型(string/number/boolean)
利用 Set 的天然去重能力,最简洁安全:
function unique<t extends number string boolean>(arr: T[]): T[] {
return [...new Set(arr)];
}</t>
说明:
-
T extends number | string | boolean限定泛型只能是可被Set正确比较的原始类型; - 直接展开
Set,保留原始顺序; - 返回类型自动推导为
T[],调用时无需手动指定泛型。
通用版:支持任意类型(含对象),带自定义比较逻辑
当数组含对象、函数等引用类型时,Set 默认无法识别“相等”,需提供比较函数:
function uniqueBy<t>(arr: T[], compareFn: (a: T, b: T) => boolean): T[] {
if (arr.length === 0) return [];
const result: T[] = [arr[0]];
for (let i = 1; i compareFn(prev, item))) {
result.push(item);
}
}
return result;
}</t>
使用示例:
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 1, name: 'Alice' },
];
const uniqueUsers = uniqueBy(users, (a, b) => a.id === b.id); // 类型仍是 { id: number; name: string }[]
进阶:用键名去重(类似 SQL 的 GROUP BY)
对对象数组按某个属性去重,更常用且类型安全:
function uniqueByProperty<t k extends keyof t>(arr: T[], key: K): T[] {
const seen = new Set<any>();
return arr.filter(item => {
const value = item[key];
if (seen.has(value)) return false;
seen.add(value);
return true;
});
}</any></t>
优点:
- 类型
K extends keyof T确保key是T的合法属性名; - 返回类型仍为
T[],完全保留原类型信息; - 自动支持联合类型属性(如
id?: number)。
注意事项与最佳实践
避免常见陷阱:
- 不要写
function unique<t>(arr: T[]): T[]</t>而不做约束——它允许传入对象数组却用Set去重,结果不符合预期; - 若需深度比较对象,应明确要求传入
compareFn,而不是试图在泛型里自动处理(TS 无法在编译期做运行时深度相等判断); - 优先用
filter + some或reduce而非indexOf,因后者对对象数组总是返回 -1,失去意义。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











