0

I'm looking for a way to use the value assigned to an enum item as the key in a dictionary, but I'm not sure of the proper way to do it or if this has a specific technical name. I'll elaborate:

We have a String Enum that is used to declare the posible states that an entity can be in.

export enum EOrderStatus {
    PENDING = 'PEND',
    ON_HOLD = 'OHDL',
    BLOCKED = 'BLCK',
    // rest of statuses
}

We also have a dictionary that defines how to display each of these states in the UI (for example purposes here I'll use colors):

export const STATUS_COLOR_DICT = {
    'PEND': 'grey',
    'OHLD': 'yellow',
    'BLCK': 'red',
    // rest of statuses
    'INVALID' : 'purple' // fallback for when the string doesn't match any known status
};

export const FALLBACK_CODE_STATUS = 'INVALID';

Now in this situation I can use a string to look up the color for a status:

public decideColorForStatusCode(statusCode: string) {
    return STATUS_COLOR_DICT[statusCode] || STATUS_COLOR_DICT[FALLBACK_CODE_STATUS];
}

What we'd like to avoid is having to use the string PEND in two different places, in case the definition for a state changes (these string codes are defined by a backend API that we depend on). But trying to use EOrderStatus.PENDING as the key for the STATUS_COLOR_DICT instead of 'PEND' gives me an error:

export const STATUS_COLOR_DICT = {
    EOrderStatus.PENDING: 'grey',
}

for the . (dot) and the : (colon)

',' expected.ts(1005)

and surrounding with ( and ) gives a different error

export const STATUS_COLOR_DICT = {
    (EOrderStatus.PENDING): 'grey',
}

Property assignment expected.ts(1136)

What did seem to work is to surround it with square brackets [ and ]. However I'm not sure if that's the correct way to do this.

export const STATUS_COLOR_DICT = {
    [EOrderStatus.PENDING]: 'grey',
}

Does this have a name? Does this produce a key with the PEND name? Is this abusing the type system or is this an acceptable usage? Is this specific to typescript or is this something that comes from javascript?

If not, what is the way to do this in order to avoid repeating the string?

Paul Wheeler
  • 18,988
  • 3
  • 28
  • 41
frozenkoi
  • 3,228
  • 22
  • 33
  • 3
    That is the correct way to do it. Apparently doing so is making use of [computed property names](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#computed_property_names), at least on the JS side of things. – msbit May 12 '21 at 05:38
  • Ah yes. Thanks. Having the "name of the thing" helps clarify this a lot. I assume that since the enum is declared at compile time then when the computation is done for the dictionary it is done with values that cannot change right? – frozenkoi May 12 '21 at 05:44
  • 1
    You could theoretically change enum values at runtime, but TypeScript won't allow it unless you @ts-ignore the error – Roberto Zvjerković May 12 '21 at 05:51
  • 1
    You can also declare a type for your dict as `const STATUS_COLOR_DICT: Record = ...` if you want to make sure that all order statuses are listed in the dict. Typescript will complain if you forget to specify a newly added status into the color dict. – Nikita Ivanov May 12 '21 at 07:24

0 Answers0