Skip to content

Instantly share code, notes, and snippets.

@SephReed
Last active July 21, 2021 07:04
Show Gist options
  • Save SephReed/46bd254b316152f38186d83109394791 to your computer and use it in GitHub Desktop.
Save SephReed/46bd254b316152f38186d83109394791 to your computer and use it in GitHub Desktop.
type UnionToIntersection<U> = (
U extends any ? (k: U) => void : never
) extends (k: infer I) => void
? I
: never
type SubpropertyMerge<T> = (
T extends object ? (
T extends string | number | ((...args: any) => any) | symbol | boolean ? T
: { [K in keyof T]: SubpropertyMerge<T[K]> }
) : T
);
function smoosh<T extends object>(objs: T[]): SubpropertyMerge<UnionToIntersection<T>> {
let out = {} as any;
Object.entries(objs).forEach(([key, value]) => {
if (typeof value === "object" && out[key]) {
out[key] = smoosh([out[key], value]);
} else {
out[key] = value;
}
})
return out;
}
// if you don't define the generic, this won't work
const eg = smoosh<
{ foo: {a: 1}}
| { foo: {b: 2}}
>([
{ foo: {a: 1}},
{ foo: {b: 2}}
]);
eg.foo.a
eg.foo.b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment