如何像typescript中的rest操作符那样对对象合并进行类型注释



我有这个函数可以合并任意数量的对象

function merge(...objs) {
return objs.reduce((res, cur) => {
for (const key in cur) {
res[key] = cur[key]
}
return res;
}, {});
}

起初我认为这个函数不能类型注释,但后来我尝试了rest参数,这与我的merge函数非常相似

const obj = {
...{ name: { ownName: 'Lewis' } },
...{ link: 'google.com' }
}
type Obj = typeof obj // I can happily get the Obj type

然后我想到了这个想法:当你事先不知道类型时,使用泛型。但是如何定义rest泛型类型呢function merge<T, U, V...>(...objs: Array<T | U | V...>)

推断rest参数的最佳方法是使用可变元组类型

// credits goes to https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
k: infer I
) => void
? I
: never;
function merge<T extends Record<PropertyKey, unknown>,
Objs extends T[]
>(...objs: [...Objs]):UnionToIntersection<Objs[number]>
function merge<T extends Record<PropertyKey, unknown>,
Objs extends T[]
>(...objs: [...Objs]) {
return objs.reduce((acc, obj) => ({
...acc,
...obj
}), {});
}
const result = merge({ a: 1 }, { b: 2 })
result.a // ok
result.b // ok

游乐场

在这里,在我的博客中,你可以找到更多的推理技巧。

至于返回类型

Objs[number]-被推断为数组中所有元素的并集UnionToIntersection-取并并

注:尽量避免打字稿的变化。你可以在这里找到如何处理它们的信息

最新更新