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

TypeScript如何推断多类组合的类返回类型并生成交叉类型

TypeScript 实现动态扩展类并正确推断返回类型

你的核心问题在于当前Compose函数的返回类型使用了未定义的typeof Base造成循环引用,且泛型处理没有正确提取扩展类的实例类型并交叉。要让TS正确识别所有扩展方法,需要调整Compose的类型定义,使其返回的构造函数实例类型包含所有扩展类的方法交叉。

步骤1:保留类型工具函数

首先保留UnionToIntersection(用于将联合类型转为交叉类型,合并所有扩展的方法):

export type UnionToIntersection<U> = 
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

步骤2:重构Compose函数的类型与实现

调整泛型定义,自动推断扩展类的类型,并让返回的构造函数实例类型为所有扩展类实例的交叉类型(如果需要基于已有基类扩展,可修改Composed的继承目标):

// 如果有基础核心类,可替换这里的空类
class CoreBase {
  baseMethod() {
    console.log("基础方法");
  }
}

const Compose = <E extends new (...args: any[]) => any>(
  ...extensions: E[]
): new (...args: any[]) => CoreBase & UnionToIntersection<InstanceType<E>> => {
  // 创建继承基础类的临时类
  class Composed extends CoreBase {}
  
  // 将所有扩展类的原型方法合并到临时类原型
  extensions.forEach(extension => {
    Object.assign(Composed.prototype, extension.prototype);
  });
  
  // 断言为目标类型,让TS识别合并后的方法
  return Composed as new (...args: any[]) => CoreBase & UnionToIntersection<InstanceType<E>>;
};

步骤3:使用Compose扩展Base类

现在定义你的扩展类,然后通过Compose合并,Base继承后就能自动识别所有扩展方法:

// 示例扩展类1
class Extension1 {
  extensionMethod1() {
    console.log("扩展方法1");
  }
}

// 示例扩展类2
class Extension2 {
  extensionMethod2() {
    console.log("扩展方法2");
  }
}

// 继承Compose合并后的类
class Base extends Compose(Extension1, Extension2) {
  customMethod() {
    this.baseMethod(); // 识别CoreBase的方法
    this.extensionMethod1(); // 自动识别Extension1的方法
    this.extensionMethod2(); // 自动识别Extension2的方法
  }
}

关键说明

  • 用InstanceType<E>提取每个扩展类的实例类型,再通过UnionToIntersection将联合类型转为交叉类型,确保所有扩展方法都能被TS识别。
  • 避免了原代码中typeof Base的循环引用问题,改为基于明确的基础类(或空类)+ 扩展交叉类型的返回定义。
  • 无需手动传入泛型参数,TS会自动推断传入的扩展类类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 03:58:38