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

TypeScript如何实现仅接收number类型属性键的泛型函数

限定取对象number类型属性的TS函数实现

目标效果

实现getNumber函数,类型规则如下:

  • 传入对象上值为number类型的属性键时,返回值类型为number(支持字面量值精准推导)
  • 传入对象上值非number类型的属性键时,直接触发TS编译报错

预期代码表现:

const a = getNumber({a: 3, b: "three"}, "a"); // 编译通过,a类型为number(或字面量类型3)
const b = getNumber({a: 3, b: "three"}, "b"); // 编译不通过

原有实现的缺陷

之前的实现通过映射类型把非number属性的值类型标记为never,只能做到传入非number键时返回值为never类型,无法直接拦截这类非法键的传入,且泛型场景下TS无法正确识别t[k]为number类型:

type NumberOnly<T> = {
    [k in keyof T]: T[k] extends number ? number : never;
}
const getNumber = <T extends Record<string, any>, 
                   K extends  keyof NumberOnly<T>>(t: T, k: K):NumberOnly<T>[K] 
     => t[k];

可直接使用的实现

注意:该实现依赖TypeScript 4.1及以上版本支持的键重映射(as 子句)语法,低版本TS无法使用

核心是用键重映射语法,直接过滤出对象中所有值为number类型的键,把泛型K约束为这类合法键的联合类型,从入参阶段就拦截非法键:

// 提取对象T中所有值为number类型的键
type NumberKeys<T> = keyof {
  [K in keyof T as T[K] extends number ? K : never]: T[K]
};

const getNumber = <T extends Record<string, unknown>, K extends NumberKeys<T>>(
  obj: T,
  key: K
): T[K] => obj[key];

效果说明

  • 传入合法number属性键时,返回值会自动推导为对应属性的类型,默认支持数值字面量精准推导,比如传入{a:3, b:"three"}取a,返回类型就是字面量3
  • 传入非number属性键时,TS会直接报类型错误,提示该键不属于合法的number类型属性键范围
  • 泛型场景下可以正确识别返回值为number类型,不会出现类型不兼容的问题

如果不需要字面量精准推导,只需要返回值统一为number类型,调整NumberKeys的映射值即可:

type NumberKeys<T> = keyof {
  [K in keyof T as T[K] extends number ? K : never]: number
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 11:01:23