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();
关键改动说明
- UnionToIntersection工具类型:利用TypeScript条件类型的特性,将联合类型转换为交叉类型,确保多个模块的方法能被合并到同一个类型中。
- Core类型调整:通过
UnionToIntersection<ModulesMaps[T]>将多个模块的接口交叉,让返回的client同时拥有所有传入模块的方法。 - 传参修正:多模块时传入数组元素为具体的模块枚举值,而非单个联合类型元素,让TypeScript正确推断泛型的联合类型。
内容的提问来源于stack exchange,提问作者weiceshi
相关产品推荐
相关产品推荐

