如何让TypeScript自动推断多对象合并函数的返回类型?
让TypeScript自动推断merge函数的返回类型
嗨,这个问题很常见!你的merge函数现在用了any[]作为参数类型,这就导致TypeScript完全没办法追踪传入对象的具体类型,自然没法自动推断result的类型。咱们可以通过泛型+递归类型的方式来修复这个问题,让TypeScript精准捕获每个输入对象的类型,然后自动生成合并后的结果类型。
解决方案:给merge函数添加泛型支持
首先,我们需要定义一个辅助类型来递归合并数组中所有对象的类型,然后给merge函数加上泛型参数,让它能捕获每个传入对象的类型:
// 辅助类型:递归合并数组中的所有对象类型 type MergeObjects<T extends object[]> = T extends [infer First, ...infer Rest] ? First & MergeObjects<Rest> : {}; export function merge<T extends object[]>(...objects: [...T]): MergeObjects<T> { // 用类型断言告诉TS初始值的类型,确保类型匹配 return objects.reduce((acc, current) => ({ ...acc, ...current }), {} as MergeObjects<T>); }
测试你的例子
现在用你原来的代码测试一下,TypeScript就能自动推断result的精确类型了:
const a = { name: '' }; const b = { id: 1 }; const c = { prop: '' }; const result = merge(a, b, c); // result的类型会被自动推断为:{ name: string; } & { id: number; } & { prop: string; } // 实际使用时TS会自动简化为等价的 { name: string; id: number; prop: string; }
处理属性覆盖的情况
如果传入的对象有重复属性(运行时后面的对象会覆盖前面的),TypeScript也能正确推断最终的类型:
const d = { name: 'Alice' }; const e = { name: 'Bob', age: 20 }; const merged = merge(d, e); // merged的类型是 { name: string; age: number; } // 完美对应运行时后面的name属性覆盖前面的逻辑
为什么原来的函数不行?
你原来的函数用了any[]作为参数类型,这相当于告诉TypeScript“我不关心这些对象的具体类型”,所以TS只能把返回值推断为模糊的{}或者any,自然没法自动生成精确的result类型。而泛型参数T extends object[]会让TS记住每个传入对象的具体类型,再通过MergeObjects类型把这些类型合并起来,最终就能得到和运行时逻辑完全匹配的返回类型啦。
内容的提问来源于stack exchange,提问作者undefined
相关产品推荐
相关产品推荐

