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

如何在TypeScript中编写类型安全的按对象属性排序泛型函数

泛型按对象属性排序函数的正确实现

你之前的泛型写法逻辑错误,string extends T完全不符合TypeScript的泛型约束规则。要实现类型精确化和属性合法性校验,需要结合keyof操作符与泛型约束,确保传入的属性是对象的合法字段,且属性值支持toLowerCase()方法。

最终实现代码

function sortByProperty<T, K extends keyof T>(
  objects: T[],
  property: K
): T[] {
  // 创建数组副本避免修改原数组(若业务允许修改原数组,可直接用objects.sort)
  return [...objects].sort((a, b) => {
    // 泛型约束已确保property是T的合法属性,断言为string是因为我们只传入字符串类型的属性
    const valueA = (a[property] as string).toLowerCase();
    const valueB = (b[property] as string).toLowerCase();

    if (valueA < valueB) return -1;
    if (valueA > valueB) return 1;
    return 0;
  });
}

关键优化点说明

  1. 属性合法性校验

    • 泛型<T, K extends keyof T>:T定义数组元素的类型,K被约束为T的所有属性名,传入非法属性时TypeScript会直接报错,比如给User类型传入"invalidProp"会提示类型错误。
    • 自动校验属性值类型:当传入属性对应的类型不是string时,TypeScript会因为toLowerCase()的调用报错,比如传入age(number类型)时会提示错误。
  2. 保留原数组类型
    函数返回类型为T[],调用后返回的数组会完整保留原对象的类型信息,能获得精准的类型提示。

  3. 避免副作用
    用[...objects]创建原数组的浅拷贝后再排序,防止原数组被意外修改。

调用示例

// 定义测试类型
interface Product {
  name: string;
  price: number;
}

const products: Product[] = [
  { name: "Laptop", price: 999 },
  { name: "mouse", price: 25 },
  { name: "Keyboard", price: 50 },
];

// 按name排序(合法,name是string类型)
const sortedProducts = sortByProperty(products, "name");
// 错误示例:传入price会报错,因为price是number类型,无法调用toLowerCase
// const sortedByPrice = sortByProperty(products, "price");

简化排序逻辑(可选)

可以用localeCompare简化字符串比较逻辑:

return [...objects].sort((a, b) => 
  (a[property] as string).toLowerCase().localeCompare((b[property] as string).toLowerCase())
);

内容的提问来源于stack exchange,提问作者MrSolarius

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 06:09:50