TypeScript中如何为对象的泛型键类型指定数值类型约束
问题核心原因
你的泛型定义存在两个逻辑错误:
- 泛型参数的定义顺序错误,I的默认值依赖后定义的K,TypeScript无法完成依赖推导
- 你给I设置的是泛型默认值而非类型约束,TypeScript不会主动校验入参是否符合I的类型要求,自然无法识别I[K]为number类型
修正后的实现代码
首先补充缺失的SortMethod枚举定义:
enum SortMethod { asc = 'asc', desc = 'desc' }
调整泛型逻辑后的函数实现:
const sortMerge = < K extends PropertyKey, T extends Record<K, number>, >( arrays: T[][], key: K, sortMethod = SortMethod.asc, ): T[] => { const indexesOfArrays = arrays.map(() => 0); const mergedSorted: T[] = []; while (arrays.some((array, i) => array.length > indexesOfArrays[i])) { const currentItemsOfArrays = arrays.map( (array, arrayIndex) => array[indexesOfArrays[arrayIndex]], ); const comparison = currentItemsOfArrays.map((item) => item ? item[key] : (sortMethod === SortMethod.asc ? Infinity : -Infinity), ); const nextArrayIndex = comparison.indexOf( Math[sortMethod === SortMethod.asc ? 'min' : 'max'](...comparison), ); const nextItem = currentItemsOfArrays[nextArrayIndex]; mergedSorted.push(nextItem); indexesOfArrays[nextArrayIndex]++; } return mergedSorted; };
校验效果验证
你给出的测试用例可以完全符合预期:
const missingKey = [ { a: 1 } ]; const valid = [ { a: 2, b: 3 } ]; const anotherValid = [ { c: 3, b: 4 } ]; // 会触发类型错误:missingKey的元素不存在属性'b' sortMerge([missingKey, valid], 'b') // 返回值类型为 ({ a: number, b: number } | { c: number, b: number })[],符合预期 sortMerge([valid, anotherValid], 'b')
修正逻辑说明
- 调整泛型定义顺序:先声明键类型K,再声明数组项类型T,直接给T增加强制约束
T extends Record<K, number>,要求所有数组项必须存在K属性且属性值为number类型,TypeScript会主动对入参做校验 - 删除冗余的I泛型参数,简化泛型逻辑,避免不必要的推导冲突
- 显式声明返回值类型为T[],类型推导更稳定
内容的提问来源于stack exchange,提问作者Gergő Horváth
相关产品推荐
相关产品推荐

