Sure, you can just write:
Map<String, Object> widerMap = new Map<String, sObject>();
No casting is required to make this work. However, this is due to a bug in the compiler. If you use this technique, be very careful not to try and store an invalid data type in the value, or you'll get a runtime exception.
Objects are passed by reference, which means that two variables can refer to the same place in memory. You can read a much longer explanation here.
As a simple example:
Account a = new Account(Name='Demo');
Account b = a;
b.Name = 'Demo 2';
System.debug(a.Name); // Demo 2
To fix this, you must create all new objects. For Lists, we have the deepClone method:
If you modify an sObject after it is placed in the key, its hashCode() value changes, and the value will become "lost" in the map. There are some hacks to fix this, but you should not rely on such hacks.
Map<ContractLineItem, Decimal> cliWithNbrMap = new Map<ContractLineItem, Decimal>();
ContractLineItem key = new ...