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

TypeScript多Module类型传入编译错误问题求解

问题解决:多模块组合的TypeScript类型修正

问题原因

原代码中,当传入包含多个模块类型的数组时,泛型T被推断为Module.Chat | Module.Video联合类型,此时ModulesMaps[T]会解析为ChatModule | VideoModule联合类型,最终Core<T>变成CommonModule & (ChatModule | VideoModule)——这意味着返回的client只能是CommonModule加上其中某一个模块的组合,而非同时拥有所有模块的方法,因此无法同时调用getVideoModule()和getChatModule()。

另外需要注意:正确的多模块传参应该是[Module.Chat, Module.Video](数组包含多个元素),而非[Module.Chat | Module.Video](数组单个元素为联合类型)。

修改后的代码

export enum Module {
  'Video' = 0,
  'Chat',
}

export interface ModulesMaps {
  [Module.Video]: VideoModule;
  [Module.Chat]: ChatModule;
}

export interface VideoModule {
  getVideoModule(): string;
}

export interface ChatModule {
  getChatModule(): string;
}

export interface CommonModule {
  init(): void;
}

// 工具类型:将联合类型转换为交叉类型
type UnionToIntersection<U> = 
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

// 调整Core类型:交叉所有传入模块对应的类型
type Core<T extends Module> = CommonModule & UnionToIntersection<ModulesMaps[T]>;

// 修正createClient的泛型与参数定义
export function createClient<T extends Module>(modules: readonly T[]): Core<T>{
  // 实际业务逻辑实现
  return undefined as unknown as Core<T>;
}

// 单模块调用(正常)
let client1 = createClient([Module.Video]);
client1.getVideoModule();
client1.init();

let client2 = createClient([Module.Chat]);
client2.getChatModule();
client2.init();

// 多模块组合调用(现在正常)
let client3 = createClient([Module.Chat, Module.Video]);
client3.getVideoModule();
client3.getChatModule();
client3.init();

关键改动说明

  1. UnionToIntersection工具类型:利用TypeScript条件类型的特性,将联合类型转换为交叉类型,确保多个模块的方法能被合并到同一个类型中。
  2. Core类型调整:通过UnionToIntersection<ModulesMaps[T]>将多个模块的接口交叉,让返回的client同时拥有所有传入模块的方法。
  3. 传参修正:多模块时传入数组元素为具体的模块枚举值,而非单个联合类型元素,让TypeScript正确推断泛型的联合类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 10:53:13