Taking @ford04's answer and expanding it for multiple optional values:
function safe_merge<
O1,
O2 extends { [K2 in keyof O2]: K2 extends keyof O1 ? never : O2[K2] },
O3 extends { [K3 in keyof O3]: K3 extends keyof O1 ? never : (K3 extends keyof O2 ? never : O3[K3]) },
O4 extends { [K4 in keyof O4]: K4 extends keyof O1 ? never : (K4 extends keyof O2 ? never : (K4 extends keyof O3 ? never : O4[K4])) },
O5 extends { [K5 in keyof O5]: K5 extends keyof O1 ? never : (K5 extends keyof O2 ? never : (K5 extends keyof O3 ? never : ( K5 extends keyof O4 ? never : O5[K5]))) },
O6 extends { [K6 in keyof O6]: K6 extends keyof O1 ? never : (K6 extends keyof O2 ? never : (K6 extends keyof O3 ? never : ( K6 extends keyof O4 ? never : (K6 extends keyof O5 ? never : O6[K6])))) },
O7 extends { [K7 in keyof O7]: K7 extends keyof O1 ? never : (K7 extends keyof O2 ? never : (K7 extends keyof O3 ? never : ( K7 extends keyof O4 ? never : (K7 extends keyof O5 ? never : (K7 extends keyof O6 ? never : O7[K7]))))) },
O8 extends { [K8 in keyof O8]: K8 extends keyof O1 ? never : (K8 extends keyof O2 ? never : (K8 extends keyof O3 ? never : ( K8 extends keyof O4 ? never : (K8 extends keyof O5 ? never : (K8 extends keyof O6 ? never : (K8 extends keyof O7 ? never : O8[K8])))))) },
O9 extends { [K9 in keyof O9]: K9 extends keyof O1 ? never : (K9 extends keyof O2 ? never : (K9 extends keyof O3 ? never : ( K9 extends keyof O4 ? never : (K9 extends keyof O5 ? never : (K9 extends keyof O6 ? never : (K9 extends keyof O7 ? never : (K9 extends keyof O8 ? never : O9[K9]))))))) },
>(
o1: O1,
o2: O2 = ({} as any),
o3: O3 = ({} as any),
o4: O4 = ({} as any),
o5: O5 = ({} as any),
o6: O6 = ({} as any),
o7: O7 = ({} as any),
o8: O8 = ({} as any),
o9: O9 = ({} as any),
): O1 & O2 & O3 & O4 & O5 & O6 & O7 & O8 & O9 {
return { ...o1, ...o2, ...o3, ...o4, ...o5, ...o6, ...o7, ...o8, ...o9 }
}
const obj_1 = {1:1}
const obj_2 = {2:1}
const obj_3 = {3:1}
const obj_4 = {4:1}
const obj_5 = {5:1}
const obj_6 = {6:1}
const obj_7 = {7:1}
const obj_8 = {8:1}
const obj_9 = {9:1}
// should not error
safe_merge(obj_1)
safe_merge(obj_1, obj_2)
safe_merge(obj_1, obj_2, obj_3)
safe_merge(obj_1, obj_2, obj_3, obj_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9)
// declare objects with keys conflicting with existing objects
const obj_2_1 = {2:1, 1: 1}
const obj_2_1b = {2:1, 1: undefined}
const obj_3_1 = {3:1, 1:1}
const obj_3_2 = {3:1, 2:1}
const obj_4_1 = {4:1, 1:1}
const obj_4_2 = {4:1, 2:1}
const obj_4_3 = {4:1, 3:1}
const obj_5_1 = {5:1, 1:1}
const obj_5_2 = {5:1, 2:1}
const obj_5_3 = {5:1, 3:1}
const obj_5_4 = {5:1, 4:1}
const obj_6_1 = {6:1, 1:1}
const obj_6_2 = {6:1, 2:1}
const obj_6_3 = {6:1, 3:1}
const obj_6_4 = {6:1, 4:1}
const obj_6_5 = {6:1, 5:1}
const obj_7_1 = {7:1, 1:1}
const obj_7_2 = {7:1, 2:1}
const obj_7_3 = {7:1, 3:1}
const obj_7_4 = {7:1, 4:1}
const obj_7_5 = {7:1, 5:1}
const obj_7_6 = {7:1, 6:1}
const obj_8_1 = {8:1, 1:1}
const obj_8_2 = {8:1, 2:1}
const obj_8_3 = {8:1, 3:1}
const obj_8_4 = {8:1, 4:1}
const obj_8_5 = {8:1, 5:1}
const obj_8_6 = {8:1, 6:1}
const obj_8_7 = {8:1, 7:1}
const obj_9_1 = {9:1, 1:1}
const obj_9_2 = {9:1, 2:1}
const obj_9_3 = {9:1, 3:1}
const obj_9_4 = {9:1, 4:1}
const obj_9_5 = {9:1, 5:1}
const obj_9_6 = {9:1, 6:1}
const obj_9_7 = {9:1, 7:1}
const obj_9_8 = {9:1, 8:1}
// should error
safe_merge(obj_1, obj_2_1)
safe_merge(obj_1, obj_2_1b)
safe_merge(obj_1, obj_2, obj_3_1)
safe_merge(obj_1, obj_2, obj_3_2)
safe_merge(obj_1, obj_2, obj_3, obj_4_1)
safe_merge(obj_1, obj_2, obj_3, obj_4_2)
safe_merge(obj_1, obj_2, obj_3, obj_4_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5_1)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5_2)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6_1)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6_2)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6_5)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_1)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_2)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_5)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_6)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_1)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_2)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_5)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_6)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_7)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_1)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_2)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_5)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_6)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_7)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_8)