Unfortunately there is no way to convert a union type into an intersection type. This is also evident by the way Object.assign is defined:
assign<T, U>(target: T, source: U): T & U;
assign<T, U, V>(target: T, source1: U, source2: V): T & U & V;
assign<T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W;
assign(target: object, ...sources: any[]): any;
lib.d.ts provides several strongly typed versions for up to 3 sources, and for more sources just becomes an array of any with no type safety.
You could use a similar approach:
// Public signatures
function arrayToObject<T>(array:[T]):T
function arrayToObject<T, T2>(array:[T, T2]):T & T2
function arrayToObject<T, T2, T3>(array:[T, T2, T3]):T & T2 & T3
function arrayToObject<T, T2, T3, T4>(array:[T, T2, T3, T4]):T & T2 & T3 & T4
function arrayToObject<T>(array:T[]):T // for more or dynamic values
// Implementation signature
function arrayToObject<T>(array:T[]):T {
return array.reduce((r,c) =>Object.assign(r,c))
}