10

EDIT

As comment suggests, Enum is not part of JavaScript but part of TypeScript. I intentionally left original title as one may make mistake like me.


I have two enums with the same keys but different values.

enum RowStates {
    editing = 0,
    sentToApproval,
    approved
    // ...
}

enum RowColors {
    editing = '#ffffff',
    sentToApproval = '#ffffcc',
    approved = '#ccffb3'
    // ...
}

And I have some function to do convertion:

function Convert (rowState) {
// What should be here to return rowColor?
// Using switch (rowState) is obvious, but may be other solution exist?
}
1
  • 7
    emun is not a javascript keyword. Commented Mar 18, 2019 at 3:48

2 Answers 2

16

TypeScript enums allow you to do a reverse mapping:

enum RowStates {
    editing = 0,
    sentToApproval,
    approved
}

enum RowColors {
    editing = '#ffffff',
    sentToApproval = '#ffffcc',
    approved = '#ccffb3'
}

function convert(rowState: RowStates) {
    return RowColors[RowStates[rowState] as keyof typeof RowColors];
}

console.log(convert(RowStates.sentToApproval)); // prints '#ffffcc'
Sign up to request clarification or add additional context in comments.

3 Comments

I have two enums with exactly same values, only names differ. I need to convert one to another, but the solution above does not work. "Property 'X' does not exist on type 'typeof XYZEnum'. Do you have any idea why?
@Peters No idea. I've just tested the solution above and (with a minor modification), it still works in the current TypeScript version (4.3.5). I think your best bet is to ask a new question and explain what's different about your specific case.
I noticed that the difference is that for me "rowState" can be undefined, so it is declared with "?" at the end. Both enums are generated from java code and in typescript look like this: enum MyEnum {AB= 'A_B', CD= 'C_D'}. The error message is "TS2551 Property 'A_B' does not exist. Did you mean 'AB'?"
4

try

function Convert (rowState: RowStates): RowColors {
    return RowColors[RowStates[rowState]];
}

working example here

Update

As poloapolo notice in his comment in current TS 4.5.2 version (and probably in some earlier versions too) this solution produce linter error

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof RowColors

it can be avoid as follows (this is alternative to Robby answer)

function Convert (rowState: RowStates): RowColors {
  return new Map(Object.entries(RowColors)).get(RowStates[rowState]) as RowColors
}

In both solutions we can add some kind of validation in case when there is key in RowStates which not exists in RowColors

2 Comments

Accessing RowColors without casting RowState item to keyof typeof RowColors, produces this linter error: "Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof RowColors'"
@poloapolo I update answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.