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

TypeScript 泛型多维排序函数回调参数类型无法收窄问题咨询

问题原因

你当前的写法里,泛型U是传入的所有key的联合类型,sort回调的三个参数是独立的联合类型,TypeScript无法建立「当key为某个具体属性时,a、b必然对应该属性的类型」的关联关系,因此你无法通过判断key的类型收窄a、b的类型。

你之前尝试的给sort加调用时泛型的方案不生效,是因为该泛型是调用侧指定的,TypeScript不会在回调内部做参数关联推导,无法将实际传入的key和泛型参数绑定。

解决方案

将sort的参数类型定义为绑定关联的联合元组即可,修改后的完整代码如下:

export function orderBy<T, U extends keyof T>(
  array: Array<T>,
  keys: Array<U>,
  sort: (...args: { [K in U]: [key: K, a: T[K], b: T[K]] }[U]) => number
) {
    const records = keys.map(key => {
        const record = {
            key,
            uniques: Array.from(new Set(array.map(item => item[key])))
        }
    
        record.uniques = record.uniques.sort((a, b) => sort(key, a, b))
    
        return record
    })
    
    const weightOfObject = (obj: T) => {
        let weight = ''
        records.map(record => {
            let zeropad = `${record.uniques.length}`.length
            weight += record.uniques.indexOf(obj[record.key]).toString().padStart(zeropad, '0')
        })
    
        return weight
    }

    return array.sort((a, b) => weightOfObject(a).localeCompare(weightOfObject(b)))
}

实现说明

我们通过映射类型遍历所有传入的key类型U,为每个属性K生成对应的绑定参数元组[key: K, a: T[K], b: T[K]],再通过索引取值将所有元组组合成联合类型。此时sort的三个参数不再是独立的联合,而是一一绑定的关系,当你在回调中判断key的具体类型时,TypeScript会自动将a、b的类型收窄为对应属性的类型,符合你预期的写法就能正常通过类型校验了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 23:27:00