Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using an enum as a dictionary key

I'm trying to create a guaranteed lookup for a given enum. As in, there should be exactly one value in the lookup for every key of the enum. I want to guarantee this through the type system so that I won't forget to update the lookup if the enum expands. I tried this:

type EnumDictionary<T, U> = {     [K in keyof T]: U; };  enum Direction {     Up,     Down, }  const lookup: EnumDictionary<Direction, number> = {     [Direction.Up]: 1,     [Direction.Down]: -1, }; 

But I'm getting this weird error:

Type '{ [Direction.Up]: number; [Direction.Down]: number; }' is not assignable to type 'Direction'.

Which seems weird to me because it's saying that the type of lookup should be Direction instead of EnumDictionary<Direction, number>. I can confirm this by changing the lookup declaration to:

const lookup: EnumDictionary<Direction, number> = Direction.Up; 

and there are no errors.

How can I create a lookup type for an enum that guarantees every value of the enum will lead to another value of a different type?

TypeScript version: 3.2.1

like image 375
Mike Cluck Avatar asked Feb 05 '19 20:02

Mike Cluck


People also ask

Is an enum a dictionary?

Dictionaries store unordered collections of values of the same type, which can be referenced and looked up through a unique identifier (also known as a key). An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.

How do I use enum keywords?

An enum is a special "class" that represents a group of constants (unchangeable variables, like final variables). To create an enum, use the enum keyword (instead of class or interface), and separate the constants with a comma. Note that they should be in uppercase letters.

Should I use enums in Python?

Python enums are useful to represent data that represent a finite set of states such as days of the week, months of the year, etc. They were added to Python 3.4 via PEP 435. However, it is available all the way back to 2.4 via pypy. As such, you can expect them to be a staple as you explore Python programming.

How do you declare an enum in Javascript?

The easiest way to define an enum would be to use Object. freeze() in combination with a plain object. This will ensure that the enum object cannot be mutated. const daysEnum = Object.

What is an enum in Python?

Python enum is a kind of enumerations for set of symbolic names that binds a constant value. We can import it in python by importing “enum” directly. There are four classes in this module that has their different pair of names and value. These are enum, IntEnum, Flag, IntFlag.

Why can't adictionary convert someenum to enum?

Show activity on this post. The compiler complains that it cannot implicitly convert SomeEnum to Enum? Show activity on this post. I believe that's because of covariance. aDictionary will be a Dictionary<SomeEnum, SomeClass>, but in the current context it is known as Dictionary<Enum, SomeClass>.

Can I rename a value in an enum?

Renaming a value within the enum is a simple refactoring task and shouldn't break the code. If the string value matches the actual value name within the enum, the code will break in a subtle way which wouldn't be easy to debug. See also: Is this a Best Practice with Enum in C# and the comments by MK87.

How to check if a value is valid in an enum?

You can check valid values with Enum.IsDefined, you can have inline XML documentation explaining each value, and typo errors are checked by the compiler (and are caught even earlier with a capable IDE). Make sure everybody uses the values in a form MyEnum.SomeValue, and not in a form of underlying integers.


Video Answer


1 Answers

You can do it as follows:

type EnumDictionary<T extends string | symbol | number, U> = {     [K in T]: U; };  enum Direction {     Up,     Down, }  const a: EnumDictionary<Direction, number> = {     [Direction.Up]: 1,     [Direction.Down]: -1 }; 

I found it surprising until I realised that enums can be thought of as a specialised union type.

The other change is that enum types themselves effectively become a union of each enum member. While we haven’t discussed union types yet, all that you need to know is that with union enums, the type system is able to leverage the fact that it knows the exact set of values that exist in the enum itself.

The EnumDictionary defined this way is basically the built in Record type:

type Record<K extends string, T> = {     [P in K]: T; } 
like image 119
miensol Avatar answered Oct 15 '22 18:10

miensol