How to type-hint a Map whose keys are classes and values are instances of those classes?

I have a map whose keys are classes and their values are instances of those respective classes.

// JavaScript code
class A {};
class B {};

const map = new Map();

map.set(A, new A);
map.set(B, new B);

How do I type-hint this map correctly in typescript?

2 answers

  • answered 2021-11-27 11:43 tokland

    Here you go (docs, kind of):

    const map = new Map<typeof A | typeof B, A | B>();
    

  • answered 2021-11-27 14:02 Aleksey L.

    You'll need a custom map definition because the standard one expects keys to be of the same type and values as well, also it doesn't allow to setup any relation between the two.

    So it could be something like:

    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
    
    // Expect error: Argument of type 'B' is not assignable to parameter of type 'A'
    map.set(A, new B);
    

    Playground

    Docs on InstanceType<Type> utility

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum