TypeScript泛型报错:groupBy函数类型问题及修复咨询
修复TypeScript中groupBy函数的类型错误
原始代码与错误
你编写的groupBy函数及调用代码如下:
export const groupBy = <T, K extends string>(array: T[], key: K): Record<K, T> => { return array.reduce((acc, item) => { if (!acc[key]) { acc[key] = [] } acc[key].push(item) return acc }, {} as Record<K, T[]>) } const arr = [{name: "Car"}, {name: 'Color'}, {name: "Car"}] interface Data { name: string } const res = groupBy<Data[], 'Car' | 'Color'>(arr, 'name') console.log(res)
调用时出现的TypeScript错误:
Argument of type '{ name: string; }[]' is not assignable to parameter of type 'Data[][]'. Type '{ name: string; }' is missing the following properties from type 'Data[]': length, pop, push, concat, and 26 more.(2345) const arr: { name: string; }[]
问题根源
- 泛型参数传递错误:你将第一个泛型参数指定为
Data[],但函数定义中第一个泛型T是数组元素的类型,而非数组本身,导致TypeScript期望传入Data[][]类型的参数,与实际的Data[]不匹配。 - 函数返回类型定义错误:返回类型标注为
Record<K, T>,但实际返回的是Record<K, T[]>(每个键对应一个元素数组),类型不匹配。 - 键类型的约束不合理:
K extends string没有关联到元素类型T的键,无法保证key是T上存在的属性。
修复方案
调整泛型定义、参数类型和返回类型,让TypeScript能正确推断类型并提供代码提示:
修复后的完整代码
export const groupBy = <T, K extends keyof T>( array: T[], key: K ): Record<Extract<T[K], string | number | symbol>, T[]> => { return array.reduce((acc, item) => { const groupKey = item[key] as Extract<T[K], string | number | symbol>; if (!acc[groupKey]) { acc[groupKey] = []; } acc[groupKey].push(item); return acc; }, {} as Record<Extract<T[K], string | number | symbol>, T[]>); }; const arr = [{name: "Car"}, {name: 'Color'}, {name: "Car"}]; interface Data { name: string; } // 无需手动指定泛型,TypeScript会自动推断 const res = groupBy(arr, 'name'); // 或手动指定泛型(可选) // const res = groupBy<Data, 'name'>(arr, 'name'); console.log(res); // 此时res的类型为Record<'Car' | 'Color', Data[]>,能获得完整代码提示
关键修复点说明
- 泛型约束关联:将
K extends string改为K extends keyof T,确保key参数是元素类型T上存在的属性,避免传入无效键。 - 返回类型精准化:使用
Extract<T[K], string | number | symbol>提取T[K]中可作为对象键的类型(string/number/symbol),让返回值的键类型是该属性的实际取值联合类型(比如示例中的'Car' | 'Color')。 - 修正泛型传递:调用时无需手动指定键的联合类型,TypeScript会自动从数组元素的属性值中推断出结果的键类型;若手动指定泛型,只需传入元素类型
Data和属性名'name'即可。
效果验证
修复后:
- 能指定数组元素的类型(通过泛型
T或自动推断); - 结果的键类型自动推断为属性值的联合类型;
- 使用
res时,TypeScript会提供'Car'和'Color'的代码提示,且每个键对应的数组元素类型为Data。
内容的提问来源于stack exchange,提问作者Asking
相关产品推荐
相关产品推荐

