Reputation: 11984
In TypeScript I would like to store instances of a generic class (here class Foo
) in a Map
.
However, I do not get the desired results since the map values are (obviously) not typed correctly since the use of any
. Is there any way to get it done?
I am not sure about using Record
or type aliases might be worth a look.
class Foo<T> {
t: T;
}
class Bar {
// Use of any because I am not sure about the right way
map: Map<string, any> = new Map();
}
const bar = new Bar();
bar.map.set('numberEntry', new Foo<number>());
bar.map.set('stringEntry', new Foo<string>());
const n = bar.map.get('numberEntry').t;
const s = bar.map.get('stringEntry').t;
console.log(typeof n); // undefined; should be 'number'
console.log(typeof s); // undefined; should be 'string'
Please let me know if further details are needed.
Upvotes: 0
Views: 329
Reputation: 20162
First of all typeof n
is runtime check, and we have here runtime issue, as our Foo instances have no values in field t
. There is no assignment of this field in the code. new Foo<number>()
creates Foo
instance with undefined
t field. We need to pass somehow t. We can fix it in the following way:
class Foo<T> {
t: T;
constructor(t: T) {
this.t = t;
}
}
Now about typying and using any
.
If we use Set
then it is not possible to match key of the set with particular value type. We can say that this set have some possible types, in this example it would be:
Map<string, Foo<string | number>> = new Map();
So we are saying in our Map we store values of Foo
with either string
or number
fields.
BTW. If we want to have key -> value type relation we should use POJO:
const map: {
numberEntry: Foo<number>;
stringEntry: Foo<string>;
} = {
numberEntry: new Foo(1),
stringEntry: new Foo("a")
};
Upvotes: 2