假设有一个函数 X
接受任意数量的对象:
export function X<T extends object[]>(...classes: T): MergedClasses<T>;
我希望它返回该列表中每个对象的交集。
例如,给定对象 A
、B
、C
和 D
,它将类似于:
let X = A & B
X = X & C
X = X & D
// for any number of objects
但是,我想将此作为函数返回类型的类型(因此 MergedClasses
)
type MergedClasses<C extends object[]> = {
}
我知道可以执行 [K for keyof C]:
但从那里我不确定如何组合对象,因为无法分配变量。
我查看了 Lodash 的 merge typings,它只是一个带有 1、2、3、4 或 5 个对象的重载函数。所以它看起来可以合并任意数量的对象,但实际上不能合并超过 5 个。
是否可以动态合并对象,还是必须采用与 Lodash 相同的路线?
答案 0 :(得分:2)
这是使用递归定义的解决方案:
type IntersectionOf<A extends any[]> = A extends [infer T, ...infer R] ? T & IntersectionOf<R> : unknown
// type Test = {a: string} & {b: number} & {c: boolean}
type Test = IntersectionOf<[{a: string}, {b: number}, {c: boolean}]>
这是使用 this answer 中的 UnionToIntersection
帮助程序的另一种稍微混乱的解决方案,如果第一个解决方案遇到编译器的递归限制,则可能更可取:
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
type IntersectionOf<A extends any[]> = UnionToIntersection<A[number]>
// type Test = {a: string} & {b: number} & {c: boolean}
type Test = IntersectionOf<[{a: string}, {b: number}, {c: boolean}]>