TypeScript中无法将keyof T传递给接收T[]和keyof T参数的排序函数的类型错误问题
TypeScript中无法将keyof T传递给接收T[]和keyof T参数的排序函数的类型错误问题
嘿,我一眼就揪出问题所在了——你调用sortItems的时候参数顺序完全搞反啦!这就是TypeScript报错的核心原因,跟你在函数内部加多少类型检查都没关系。
先仔细对比一下函数定义和你的调用代码:
函数sortItems的签名
const sortItems = <T extends { createdAt?: string }>( items: T[], filterName: keyof T, sortValue: string, setItems: React.Dispatch<React.SetStateAction<T[]>> ) => { /* ... */ }
它的参数顺序是:要排序的数组 → 排序依据的键名 → 排序方向 → 状态更新函数
你在updateSortType里的错误调用
sortItems(filterName, newSortType, items, setItems);
你把filterName(类型是keyof T,也就是string | number | symbol)放到了第一个参数位置,但函数第一个参数需要的是T[]类型的数组,这可不就触发「类型'string | number | symbol'不能赋值给类型'T[]'」的报错了嘛!
修复方案:修正参数调用顺序
只需要把参数顺序改成和函数定义一致的即可:
const updateSortType = () => { const newSortType = (sortType === '' || sortType === 'dsc') ? 'asc' : 'dsc'; setsortType(newSortType); // 修正后的参数顺序:items → filterName → newSortType → setItems sortItems(items, filterName, newSortType, setItems); };
额外的代码优化建议
既然已经用泛型约束好了类型,我们还可以简化一些冗余的类型断言:
- 去掉
sortItems里多余的类型断言
因为filterName已经被约束为keyof T,所以直接用a[filterName]即可,不用额外的类型断言:
// 原冗余代码 const valueA = a[filterName as keyof typeof a]?.toString().toLowerCase() || ''; // 优化后 const valueA = a[filterName]?.toString().toLowerCase() || '';
- 简化
createdAt分支的判断
因为T extends { createdAt?: string },TypeScript已经知道createdAt是T的可选键,所以不用items.every(item => 'createdAt' in item),直接访问a.createdAt即可:
if (filterName === 'createdAt') { sortedItems = [...items].sort((a, b) => { const dateA = new Date(a.createdAt || ''); const dateB = new Date(b.createdAt || ''); // ... 排序逻辑 }); }
这样调整后,代码不仅类型更安全,也更简洁啦~
内容来源于stack exchange
相关产品推荐
相关产品推荐

