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

TypeScript如何基于数组字符串路径提取对象嵌套类型实现类型安全排序函数

类型安全嵌套路径数值排序函数实现

问题根源

原有实现的泛型仅约束了路径的第一层属性为目标对象的属性,没有递归校验深层路径的合法性,同时也没有约束路径最终指向的属性必须为数值类型,因此出现了合法嵌套路径被判定为类型错误、非法嵌套路径无类型提示的问题。

解决方案

通过递归工具类型生成目标对象所有合法的数值类型属性路径,再对sortByNumeric的路径参数做泛型约束,即可解决问题。

完整实现代码

export enum SortDirection {
    ASCENDING = "ASCENDING",
    DESCENDING = "DESCENDING",
}

// 递归工具类型:生成对象所有指向指定叶子类型的合法嵌套路径数组
type PathArray<T, LeafType = unknown> = T extends LeafType
  ? []
  : {
      [K in keyof T]: [K, ...PathArray<T[K], LeafType>]
    }[keyof T]

/**
 * 生成数值类型排序比较器
 * @param path 指向数值类型值的嵌套属性路径
 * @param direction 数值排序的方向
 * @returns 可直接传入Array.sort的比较函数
 */
export const sortByNumeric = <T extends object>(
    path: PathArray<T, number>, 
    direction = SortDirection.ASCENDING
) => (current: T, next: T) => {
    const extractedA = path.reduce((acc, key) => acc[key as keyof typeof acc], current) as number
    const extractedB = path.reduce((acc, key) => acc[key as keyof typeof acc], next) as number
    return direction === SortDirection.ASCENDING ? extractedA - extractedB : extractedB - extractedA
}

测试效果

const source = [
    {
        name: 'Jon',
        age: 20,
        father: {
            name: 'Jon Senior',
            age: 60,
            otherProp: 100
        }
    },
    {
        name: 'Gabriel',
        age: 25,
        father: {
            name: 'Jon Senior',
            age: 80,
            otherProp: 20
        }
    }
]

// 单层属性路径:正常运行
source.sort(sortByNumeric(['age']))
// 合法嵌套路径:正常运行,无类型错误
source.sort(sortByNumeric(['father', 'otherProp']))
// 非法嵌套路径:直接抛出类型错误,提示路径不符合约束
// source.sort(sortByNumeric(['age', 'father']))

内容的提问来源于stack exchange,提问作者Християн Христов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:24:02