I am struggling to enforce a mapping on an object in TypeScript. My goal is to define a type
or interface
that maps from ANIMAL_PLACE
to ANIMAL_TYPE
. I want the type to ensure that any object created with these mappings includes both the ANIMAL_PLACE
and ANIMAL_TYPE
keys. However, I have only been able to achieve this halfway.
export enum ANIMAL_TYPE {
dog = "dog",
cat = "cat",
fish = "fish",
foo = "foo"
}
export enum ANIMAL_PLACE {
europe = 'europe',
africa = 'africa',
asia = "asia"
}
// Despite my efforts, this type does not trigger a compiler error when ANIMAL_PLACE or ANIMAL_TYPE is missing
type AnimalPlaceToAnimalMapType = {
[ANIMAL_PLACE.africa]: [ANIMAL_TYPE.cat, ANIMAL_TYPE.fish]
[ANIMAL_PLACE.europe]: [ANIMAL_TYPE.dog]
}
// Only ANIMAL_PLACE triggers a compiler error when missing from the record
const AnimalPlaceToAnimalMapRecord: Record<ANIMAL_PLACE, ANIMAL_TYPE[]> = {
[ANIMAL_PLACE.africa]: [ANIMAL_TYPE.cat, ANIMAL_TYPE.fish],
[ANIMAL_PLACE.europe]: [ANIMAL_TYPE.dog],
};
Try out the code in this Playground
If I cannot achieve an error when either key is missing, is there a way to trigger a compiler error specifically if ANIMAL_TYPE
is omitted instead of ANIMAL_PLACE
...?