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
相关产品推荐
相关产品推荐

