I have a object map of T
with value that extends an interface / class or in a similar example members in a union. I would like to lookup the value of a key, K
in T
and determine the specific subtype or union member, i.e., I don't want the derived type to evaluate to the union or interface. Here an example of an object map with values that extend an interface
class Animal { move() { } }
class Cat extends Animal { meow() { } }
class Dog extends Animal { bark() { } }
const animalLookup: { [K in 'cat' | 'dog']: typeof Animal } = {
cat: Cat,
dog: Dog,
}
Now when I lookup a key in animalLookup
:
const result = animalLookup['cat'];
// => const result: typeof Animal;
This is expected.
What I've tried is making animalLookup
a const with as const
. This works as expect, but I loose the ability to make the index type of animalLookup
a mapped type, so I can enforce the keys.
Is there a way to make this work so that I can achieve the following while annotating animalLookup
with an index signature so I can constrain the keys
const result = animalLookup['cat'];
// => const result: typeof Cat;
EDIT: Added clarification to the question EDIT: updated example to correct values to constructor vs instance types