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

TypeScript如何定义泛型获取类父子实例所有number类型属性的键

实现方案

完整可运行代码如下:

// 工具类型:提取泛型T中值类型为number的属性键
type NumberPropertyKeys<T> = {
  [K in keyof T]: T[K] extends number ? K : never
}[keyof T]

class A {
  foo = 1;
  xoo = 'abc';

  get(): Record<NumberPropertyKeys<this>, number> {
    const result = {} as Record<NumberPropertyKeys<this>, number>;
    // 运行时遍历实例属性,过滤出值为number的属性
    for (const key in this) {
      const val = this[key];
      if (typeof val === 'number') {
        result[key as NumberPropertyKeys<this>] = val;
      }
    }
    return result;
  }
}

class B extends A {
  bar = 2;
  zar = [1, 2, 3];

  init() {
    const res = this.get();
    // 此处输入res. 会自动补全 foo、bar 两个属性
    console.log(res.foo, res.bar);
  }
}
原理解析
  • 工具类型NumberPropertyKeys:通过映射类型遍历泛型T的所有属性键,对每个属性做类型校验,如果属性值类型是number则保留键名,否则映射为never,最后通过索引访问[keyof T]过滤掉所有never值,得到符合要求的属性键的联合类型。该工具会自动排除函数类型、字符串、数组等非number类型的属性,天然满足过滤get、init、xoo、zar的要求。
  • 多态this类型:父类get方法的返回类型中直接使用this作为泛型参数,TS在处理类继承场景时,会将调用方法的实际实例类型(子类B的实例类型)代入this,而非固定使用父类A的类型,因此可以同时捕获父类和子类的所有属性。
  • 运行时逻辑和类型定义对齐:get方法内部通过for...in遍历实例所有可枚举属性(包含继承自父类的属性),用typeof判断值类型后收集,保证运行时返回的对象和TS推导的类型完全一致,不会出现类型和实际值不符的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:36:00