To create a customized map definition, you'll need to deviate from the standard one which requires keys and values to be of the same type without any relation setup between them.
Here's an example of how you can do it:
type Constructor = new (...args: any) => any;
interface ConstructorMap {
clear(): void;
delete(key: Constructor): boolean;
get<K extends Constructor>(key: K): InstanceType<K> | undefined;
has(key: Constructor): boolean;
set<K extends Constructor>(key: K, value: InstanceType<K>): this;
readonly size: number;
}
class A { a = '' };
class B { b = 1 };
const map: ConstructorMap = new Map();
map.set(A, new A);
map.set(B, new B);
const a = map.get(A); // A | undefined
// This will result in an error: Argument of type 'B' is not assignable to parameter of type 'A'.
map.set(A, new B);
Playground
Check out the documentation on the InstanceType<Type>
utility for more information.