Is it possible to type a Map<K, V> in such a way where the type of the value will depend on the type of the key, without specifying the type of the key on creation of the map?
Example:
abstract class BaseA { a() {} }
class ConcreteA1 extends BaseA { a1() {} }
class ConcreteA2 extends BaseA { a2() {} }
abstract class BaseB { b() {} }
class ConcreteB extends BaseB { b1() {} }
const map = new Map<???, ???>();
map.set(BaseA, ConcreteA1); // should be OK
map.set(BaseA, ConcreteA2); // should be OK
map.set(BaseB, ConcreteB); // should be OK
map.set(BaseA, ConcreteB); // should error
Bonus: can we make be an error too?
Since BaseA is abstract, this should be an error as well, if possible, as BaseA does not satisfy new (...args: any[]) => BaseA, since it is not instantiable.
map.set(BaseA, BaseA); // should error as a bonus
UPDATE:
I need to keep a map of dependency implementations, such as the values are concrete implementations (extend) of the key (base type).