如何将TypeScript泛型对象数组合并为单个对象类型?
如何将泛型对象数组合并为单个对象类型而非联合类型
我希望将泛型对象数组合并为单个对象,但当前生成的是联合类型。如何获取合并后的对象类型,例如{key: string; boo?: string; foo?: string;}?
type PluginType<T extends Record<string, unknown> = {}> = T & { key: string; } function renderer<T extends Record<string, unknown> = {}>(plugins?: Array<PluginType<T>>) { const test = {} as T; return () => test; } // ---cut--- const plugins1: PluginType<{boo?: string}> = { key: '', boo: '' }; const plugins2: PluginType<{foo?: string}> = { key: '', foo: '' }; const render = renderer([plugins1, plugins2]); render().boo render().foo
解决方案
要实现合并泛型对象类型的需求,需要让renderer函数推断数组中所有插件的泛型参数并将它们合并,而非限制为单一T类型。具体修改如下:
type PluginType<T extends Record<string, unknown> = {}> = T & { key: string; } // 从PluginType中提取传入的泛型数据部分 type ExtractPluginData<P> = P extends PluginType<infer T> ? T : never; // 将联合类型合并为单个对象类型 type MergeUnion<T> = T extends infer U ? { [K in keyof U]: U[K] } : never; function renderer<P extends PluginType[]>(plugins?: P) { // 合并所有插件的泛型数据类型 type MergedData = MergeUnion<ExtractPluginData<P[number]>>; const test = {} as MergedData; return () => test; } // ---cut--- const plugins1: PluginType<{boo?: string}> = { key: '', boo: '' }; const plugins2: PluginType<{foo?: string}> = { key: '', foo: '' }; const render = renderer([plugins1, plugins2]); render().boo; // 类型检测正常 render().foo; // 类型检测正常
关键逻辑说明:
ExtractPluginData<P>:从每个PluginType实例中提取出传入的泛型T部分;P[number]:获取插件数组中所有元素的联合类型;MergeUnion:将联合类型转换为合并后的对象类型,保留所有属性;- 修改后的
renderer通过P extends PluginType[]推断插件数组类型,再通过类型工具合并得到最终返回类型。
内容的提问来源于stack exchange,提问作者Yongbeen Im
相关产品推荐
相关产品推荐

