Home > database >  Creating a Map where keys of type Generic<T> must be mapped to values of type T
Creating a Map where keys of type Generic<T> must be mapped to values of type T

Time:10-04

I have a generic class ImmutableGeneric<T> and a few instances of this class.

I would like to create a Map where each key is an instance of ImmutableGeneric, and a key of type ImmutableGeneric<T> must be associated with a value of type T.

class ImmutableGeneric<T>{
    constructor(
        public readonly value: T
    ){}
}

const NUMBER = new ImmutableGeneric(1)
const STRING = new ImmutableGeneric('hi')


const map = new Map<ImmutableGeneric<???>,???>()

// Ok
map.set(NUMBER, 5)
map.set(STRING, 'hello')

// Wrong, there should be a warning here
map.set(NUMBER, 'clearly not a number')

Is this possible?

CodePudding user response:

Currently there is no way to associate the two, but you can extend Map:

class ImmutableGenericMap extends Map<ImmutableGeneric<unknown>, unknown> {
    set<T>(key: ImmutableGeneric<T>, value: T) {
        return super.set(key, value);
    }
}

Playground

You can do the same sort of thing for the other methods as well (get, has, delete, entries, forEach).

Unfortunately, even interface merging cannot get around this, since if you try to add in an overload to account for this, only the first (original) overload will be used. You'll end up having to pass in the generics for the overload yourself... and that's not DRY at all, so I'd just stay with extending Map.

  • Related