Home > database >  Merged enums comparison -- Typescript
Merged enums comparison -- Typescript

Time:07-28

I understand how to merge two enums into one by doing the following.

enum Reptiles {
  Lizard = "Lizard",
  Snake = "Snake"
}

enum Mammals {
  Kangaroo = "Kangaroo",
  Dolphin = "Dolphin"
}

const Animals = { ...Mammals, ...Reptiles }
type Animals = typeof Animals

However, my issue comes when trying to perform comparisons on the code.

// This presents the following error 
// Error -- Type 'Mammals' is not assignable to type '{ Lizard: Reptiles.Lizard; Snake: Reptiles.Snake; Kangaroo: Mammals.Kangaroo; Dolphin: Mammals.Dolphin; }'.
const mySpiritAnimal: Animals = Animals.Kangaroo; 

// And this presents the following error 
// Error -- Argument of type '{ Lizard: Reptiles.Lizard; Snake: Reptiles.Snake; Kangaroo: Mammals.Kangaroo; Dolphin: Mammals.Dolphin; }' is not assignable to parameter of type 'Mammals'.
[Animals.Kangaroo].includes(mySpiritAnimal);

How do I merge enums and actually be able to use them effectively in comparisons etc?

**EDIT If I then use the following code to type the enum properly, it still highlights a tsc error when changing the comparator in the array to Lizard.

type Animals = typeof Animals[keyof typeof Animals];


//ok
const mySpiritAnimal: Animals = Animals.Kangaroo;

//ok
[Animals.Kangaroo].includes(mySpiritAnimal);

// NOT ok -- Argument of type 'Mammals.Kangaroo' is not assignable to parameter of type 'Reptiles'.ts(2345)
[Animals.Lizard].includes(mySpiritAnimal);

CodePudding user response:

type Animals = typeof Animals is the type of the object that contains the enum members. You want the type of the enum values, which would be type Animals = typeof Animals[keyof typeof Animals]

const Animals = { ...Mammals, ...Reptiles }
type Animals = typeof Animals[keyof typeof Animals] // just Reptiles | Mammals


//ok
const mySpiritAnimal: Animals = Animals.Kangaroo; 

//ok
[Animals.Kangaroo].includes(mySpiritAnimal);

Playground Link

CodePudding user response:

I got around this issue by being more explicit with my enum in the following manner.

enum Reptiles {
  Lizard = "Lizard",
  Snake = "Snake"
}

enum Mammals {
  Kangaroo = "Kangaroo",
  Dolphin = "Dolphin"
}

enum Animals { 
  Kangaroo = Mammals.Kangaroo,
  Dolphin = Mammals.Dolphin,
  Lizard = Reptiles.Lizard,
  Snake = Reptiles.Snake
}

//ok
const mySpiritAnimal: Animals = Animals.Kangaroo;

//ok
[Animals.Kangaroo].includes(mySpiritAnimal);

//ok (yay!)
[Animals.Lizard].includes(mySpiritAnimal);
  • Related