简体   繁体   中英

How to convert TypeScript Enum key to value and value to key

Context lets say I have the following enum with string values:

enum Fruit {
  Apple = "apple",
  Orange = "orange",
  Banana = "banana",
  Pear = "pear"
}

the user always inputs the literal string value ( "apple" , "banana" , "orange" , "pear" ) lets say from a drop down to eliminate possibility of invalid inputs - which I need to convert back to type Fruit ie something like this:

function getFruit(fruit: string): Fruit {
    switch (fruit) {
        case "apple":
        return Fruit.Apple
        case "banana":
        return Fruit.Banana
        case "orange":
        return Fruit.Orange
        case "pear":
        return Fruit.Pear
        default:
        // I DON'T WANT THIS!
        return Fruit.Pear
    }
}

Problems

  • The switch statement requires maintenance overhead
  • The getFruit() function:
    • takes any string which is not represented as a union of acceptable string values (typescript will not throw a compilation error if anything other than "apple" , "banana" , "orange" , "pear" are used.) I know i can use a union of absolute strings as the type but thats even more overhead.
    • a default case needs to be provided and a default result returned.

Question

Is there a more elegant way to do the above? maybe with type / typeof / keyof or any other operations?

I ideally want to be able to:

  • Eliminate the switch statement completely - (so no maintenance overhead)
  • getFruit() function to only take string values that are contained in the enum programatically (without manually declaring and maintaining a union of absolute strings).

ps I don't care if i need to use an alternative type rather than an enum - its the functionality that is important!

Best Attempt the closest I've got to a solution so far is:

type Fruits = "apple" | "banana" | "orange" | "pear"
let Fruit = {
  Apple = "apple",
  Orange = "orange",
  Banana = "banana",
  Pear = "pear"
}
type Fruit = keyof typeof Fruit

function parseFruit(fruit: Fruits): Fruit {
  return Object.keys(Fruit).find((key) => {
    return Fruit[key as Fruit] === fruit
  }) as Fruit
}

this still requires for string literal union type Fruits and Fruit to be managed. This solution would be 'perfect' if I could figure out how to programmatically create the string literal union type Fruits .

You can iterate over Enum values and find Fruit

function getFruit(fruit: string): Fruit | null {
    return Object.values(Fruit).find(item => item === fruit) ?? null
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM