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

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);
};

额外的代码优化建议

既然已经用泛型约束好了类型,我们还可以简化一些冗余的类型断言:

  1. 去掉sortItems里多余的类型断言
    因为filterName已经被约束为keyof T,所以直接用a[filterName]即可,不用额外的类型断言:
// 原冗余代码
const valueA = a[filterName as keyof typeof a]?.toString().toLowerCase() || '';
// 优化后
const valueA = a[filterName]?.toString().toLowerCase() || '';
  1. 简化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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 12:02:59