You need to enable JavaScript to run this app. TypeScript 如何约束泛函数参数为对应值为number的泛型键
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript 如何约束泛函数参数为对应值为number的泛型键

mkSorter函数的数值属性类型约束实现

基础工具类型定义

首先需要定义一个工具类型,从任意对象类型T中提取所有值类型为number的键名,组合成联合类型:

type NumericKeys<T> = {
  [P in keyof T]: T[P] extends number ? P : never
}[keyof T]

该工具类型的遍历逻辑:逐个判断T的键对应的值类型是否为number,匹配则保留当前键名,不匹配则返回never,最后合并所有有效键名形成联合类型。针对示例中的SomeObjectType,该工具类型会直接得到'number' | 'alsoNumber'的联合类型。

如果使用TS 4.1及以上版本,可以用键重映射的语法写出可读性更强的等价实现:

type NumericKeys<T> = keyof {
  [P in keyof T as T[P] extends number ? P : never]: T[P]
}

完整函数实现

将原函数中泛型K的约束从keyof T替换为上述NumericKeys<T>,即可实现对传入属性的类型限制,完整代码如下:

function mkSorter<
  T extends { [key: string]: unknown },
  K extends NumericKeys<T>
>(prop: K) {
  // 因K已被约束为T中值为number的键,a[prop]的类型天然为number,减法运算不会触发类型报错
  return (a: T, b: T) => a[prop] - b[prop];
}

实现效果

  • 严格类型校验:调用函数时仅可传入目标类型T中值为number的属性名,传入字符串、布尔值等非数值类型的属性时,会直接收到TypeScript的类型错误提示
  • 正常支持自动补全:由于K的约束直接与T的数值键做绑定,TypeScript在类型提示阶段可直接枚举所有合法的属性名,输入时会自动弹出可选的键名列表
  • 完全匹配使用场景:示例中mkSorter<SomeObjectType>('alsoNumber')的调用方式可正常通过类型校验,与表格组件的ColumnsType的sorter字段类型兼容

旧方案自动补全失效的原因

之前提供的绕层交叉类型的方案,之所以无法正常触发自动补全,是因为方案额外引入了NumericFields<T>的交叉类型泛型N,拉长了TypeScript对prop参数合法值的推断链路:TS无法直接从泛型T的定义一步定位到所有合法的prop候选项,需要额外推导交叉类型的键集合,这个推导过程会丢失自动补全所需的枚举信息,导致提示失效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 19:45:00