type Assign = {
[K in keyof A | keyof B]: K extends keyof A ?
K extends keyof B ?
NonNullable extends (...args: any[]) => any ?
NonNullable extends (...args: any[]) => any ?
A[K] | B[K]
: B[K]
: B[K]
: A[K]
: K extends keyof B ? B[K]
: never
}
type MergeObjectsArray =
T extends [infer F, ...infer R] ?
Assign : NonNullable>
: NonNullable
type PrettyObject = { [K in keyof T]: T[K] } & NonNullable
export function chainEventHandlers<
First extends Record,
Rest extends Record[],
>(
first: First,
...rest: Rest
): PrettyObject> {
const result: Record = { ...first }
for (const obj of rest) {
for (const key in obj) {
const value = obj[key]
const prev = result[key]
if (typeof prev === 'function' && typeof value === 'function') {
result[key] = (...args: any[]) => {
prev(...args)
return value(...args)
}
} else {
result[key] = value
}
}
}
return result as MergeObjectsArray<[First, ...Rest]>
}