1

How to check a value against a list of enum values, in TypeScript?

I.E., Java:

public enum Animal {
    CAT, DOG, BIRD, SNAKE
    public static EnumSet<Animal> Mammals = EnumSet.of(CAT, DOG);
}

Usage: Animal.Mammals.contains(myPet)

Is there a way to do something like that without predefining a helper class for each enum (which can feel a little accessive with multiple enum types)?

The best solution I have so far is:

export enum Animal {
    CAT, DOG, BIRD, SNAKE
}

export namespace Animal {
  export const Mammals = [Animal.CAT, Animal.DOG];
}

//Usage: Animal.Mammals.includes(myPet)

...Which is nice because the usage unifies the enum with the list but still requires defining both namespace and enum separately. Also, namespaces are considered outdated.

noamyg
  • 2,747
  • 1
  • 23
  • 44
  • Perhaps this solution can be adapted? https://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript – Igor Levicki Sep 20 '22 at 07:58
  • Java enums are irregular as they allow to be treated as classes. Which is quite useful but pretty much all other other languages treat enums as simple textual labels and that's it. With that said, what you've shown here is a very simple `const Mammals = new Set([Animal.CAT, Animal.DOG])`, why would an enum be relevant? Or classes? – VLAZ Sep 20 '22 at 08:00

1 Answers1

1

Enums in TypeScript are syntactic sugar for literal number or string values, so you can just use a regular Set:

enum Animal {
    CAT, DOG, BIRD, SNAKE
}

const Mammals = new Set([Animal.CAT, Animal.DOG])

Mammals.has(Animal.CAT)

It's a little odd to implement this way in TypeScript, but if you really want to access it as Animal.Mammals, you can use namespace merging:

enum Animal {
    CAT, DOG, BIRD, SNAKE
}

namespace Animal {
    export const Mammals = new Set([Animal.CAT, Animal.DOG])
}
Evan Summers
  • 942
  • 4
  • 13
  • I'd really like to have `Mammals` as part of `Animal`. Your way is cool for one enum but implementing it in a big model becomes tedious. – noamyg Sep 20 '22 at 08:05
  • @noamyg there is no difference between this and having it as part of the enum. It's exactly the same amount of effort in either case. The only thing you "win" by having `Mammals` as part of `Animal` is the namespacing. Which you can get from modules in TS, thus also irrelevant. – VLAZ Sep 20 '22 at 08:08
  • 1
    Updated answer; you can do it with namespace merging – Evan Summers Sep 20 '22 at 08:10
  • @Toggle thanks, I've just updated my question with the same solution and stated its' disadvantages ;-) – noamyg Sep 20 '22 at 08:10