如何将TypeScript函数交叉类型拆分为对象类型?
将函数交叉重载类型转换为对象类型的实现思路
要把类型A转换成目标对象类型B,可以利用TypeScript的条件类型推断和索引类型来实现,具体步骤如下:
核心实现代码
// 从单个函数类型中提取事件名与参数类型 type ExtractEventAndParams<Func> = Func extends (event: infer EventName, value: infer ParamType) => void ? { event: EventName; params: ParamType } : never; // 将事件-参数映射的联合类型转换为目标对象类型 type BuildEventObject<EventUnion> = { [EventKey in EventUnion extends { event: infer E } ? E : never]: EventUnion extends { event: EventKey; params: infer P } ? (value: P) => void : never; }; // 最终转换工具类型 type ConvertToEventObject<FuncOverloads> = BuildEventObject<ExtractEventAndParams<FuncOverloads>>; // 测试用例 type A = ((event: "click", value: []) => void) & ((event: "update", value: string) => void) & ((event: "delete", value: number) => void); // 得到目标类型B type B = ConvertToEventObject<A>;
步骤拆解
ExtractEventAndParams
借助条件类型的infer关键字,匹配符合(event: E, value: V) => void结构的函数类型,提取出事件名字面量EventName和参数类型ParamType,并包装成包含这两个字段的对象类型。如果传入的函数不符合该结构,返回never。BuildEventObject
- 首先通过
EventUnion extends { event: infer E } ? E : never从联合类型中提取所有可能的事件名,作为对象的键; - 对每个键
EventKey,筛选出联合类型中对应事件名为EventKey的条目,提取其参数类型P,构建成(value: P) => void的函数类型作为键值。
- 首先通过
ConvertToEventObject
组合前两个类型:先把原交叉函数类型转换成事件-参数映射的联合类型,再将这个联合类型转换成目标对象类型。
注:TypeScript会将交叉函数类型视为重载集合,因此
ExtractEventAndParams<A>会自动展开为{event: "click"; params: []} | {event: "update"; params: string} | {event: "delete"; params: number}的联合类型,确保后续能正确构建对象。
内容的提问来源于stack exchange,提问作者Jordan
相关产品推荐
相关产品推荐

