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

TypeScript中如何正确推断继承基类时传入的具体泛型类型

问题描述

请参考如下代码:

type secondaryObjectConstraint = {
    [key: string]: number
}

abstract class Base<TObject extends object, TSecondaryObject extends secondaryObjectConstraint> {}


type secondaryObjectType = {
    myProp: number
}

class ExtendedObject extends Base<{}, secondaryObjectType> {}

type inferSecondaryObject<M extends Base<any, any>> = M extends Base<any, infer TSecondaryObject> ? TSecondaryObject : never;

const a: inferSecondaryObject<ExtendedObject> = {};

上述示例中,变量a被推断的类型为secondaryObjectConstraint,而非预期的精确类型secondaryObjectType。

问题原因

该现象由TypeScript结构化类型系统的泛型处理规则导致:

  • 如果泛型参数仅出现在类的泛型约束声明中,完全没有参与类的实例成员(属性、方法)定义,TypeScript不会保留传入该泛型位置的具体类型,会直接将其替换为泛型的约束边界类型。
  • 示例中Base是空抽象类,TSecondaryObject没有被任何类结构引用,因此编译阶段传入的secondaryObjectType被直接替换为约束secondaryObjectConstraint,后续类型推断自然无法拿到精确类型。
修复方案

只需让泛型参数参与到Base类的结构定义中即可,最通用的做法是添加类型占位属性,不需要实际赋值使用,仅在类型层面保留泛型信息,不会产生额外运行时开销:

type secondaryObjectConstraint = {
    [key: string]: number
}

abstract class Base<TObject extends object, TSecondaryObject extends secondaryObjectConstraint> {
    // 可选占位属性,仅用于绑定泛型到类结构
    _tObject?: TObject;
    _tSecondaryObject?: TSecondaryObject;
}


type secondaryObjectType = {
    myProp: number
}

class ExtendedObject extends Base<{}, secondaryObjectType> {}

type inferSecondaryObject<M extends Base<any, any>> = M extends Base<any, infer TSecondaryObject> ? TSecondaryObject : never;

// 此时a的类型被正确推断为secondaryObjectType,赋值空对象会触发缺少myProp属性的类型报错
const a: inferSecondaryObject<ExtendedObject> = {};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 03:45:48