TypeScript中如何为泛型对象合并函数定义正确的返回类型
解决方案
1. 基础版(简单合并推导)
通过泛型递归解析传入的对象元组,将所有对象类型交叉得到最终的合并结果:
// 递归合并元组中所有对象的类型 type MergeTupleTypes<T extends object[]> = T extends [infer Curr, ...infer Rest extends object[]] ? Curr & MergeTupleTypes<Rest> : {}; function merge<T extends object[]>(...objects: T): MergeTupleTypes<T> { const temp = {} as MergeTupleTypes<T>; for (const obj of objects) { for (const key in obj) { // 运行时逻辑符合预期,类型层面已保证正确性,忽略类型警告即可 // @ts-ignore temp[key] = obj[key]; } } return temp; }
使用测试:
const result = merge({a: 1}, {b: 'test'}); // result 类型自动推导为 {a: number} & {b: string},使用效果和 {a: number, b: string} 完全一致 console.log(result.a) // 类型提示为 number console.log(result.b) // 类型提示为 string
2. 进阶版(支持同键覆盖推导)
如果需要符合运行时「后面对象同键覆盖前面」的逻辑,可以调整类型定义,优先保留后面的键类型:
type MergeOverwriteTypes<T extends object[]> = T extends [infer Curr, ...infer Rest extends object[]] ? Omit<Curr, keyof MergeOverwriteTypes<Rest>> & MergeOverwriteTypes<Rest> : {}; function merge<T extends object[]>(...objects: T): MergeOverwriteTypes<T> { const temp = {} as MergeOverwriteTypes<T>; for (const obj of objects) { for (const key in obj) { // @ts-ignore temp[key] = obj[key]; } } return temp; }
使用测试:
const result = merge({a: 1, c: false}, {a: 'hello', b: 2}); // result 类型推导为 {c: boolean, a: string, b: number},完全符合运行时实际结果
说明:通用类库的合并函数类型定义复杂度高,是因为要兼容嵌套合并、非对象参数、特殊类型值等大量边缘场景,如果你只需要处理平面对象的合并,以上方案完全可以满足需求。
内容的提问来源于stack exchange,提问作者Valerie Thiesent
相关产品推荐
相关产品推荐

