const result = merge({ a: 1 }, { a: "fdsfsd" })
The correct type is quite complex and depends on whether or not `exactOptionalPropertyTypes` is enabled.EDIT: I think this is correct for when `exactOptionalPropertyTypes` is off.
type OptionalKeys<T extends { [key in symbol | string | number]?: unknown }> = { [K in keyof T]: {} extends Pick<T, K> ? K : never }[keyof T]
function merge<
A extends { [K in symbol | string | number]?: unknown },
B extends { [K in symbol | string | number]?: unknown },
>(a: A, b: B): {
[K in Exclude<keyof B, keyof A>]: B[K]
} & {
[K in Exclude<keyof A, keyof B>]: A[K]
} & {
[K in keyof A & keyof B]: K extends OptionalKeys<B> ? A[K] | Exclude<B[K], undefined> : B[K];
}
That's for when `exactOptionPropertyTypes` is enabled. With it disabled, then you'd replace `Exclude<B[K], undefined>` with `B[K]`.As to whether this is a good idea. Ah... it's not :P