Tips for transforming TypeScript Enum properties into their corresponding values and vice versa

Situation Imagine having an enum with string values like this:

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

Users always input a specific string value ("apple", "banana", "orange", "pear") from a drop-down list to ensure valid inputs, which then needs to be converted back to the correct type Fruit. Here's an example function for that:

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'D RATHER AVOID THIS!
        return Fruit.Pear
    }
}

Challenges

  • Maintaining the switch statement can be cumbersome.
  • The getFruit() function:
    • accepts any string without restricting it to a specific set of values (Typescript won't give a compile error if an invalid value is used).
    • a default case must be provided along with a default return value.

Inquiry

Is there a more efficient way to achieve the same result? Perhaps using type/typeof/keyof or other methods?

Ideally, I'd like to:

  • Avoid using the switch statement entirely - reducing maintenance overhead.
  • Restrict the getFruit() function to only accept string values that are part of the enum automatically (without manually declaring and maintaining a union of strings).

p.s. Using a different type instead of an enum is also acceptable as long as the functionality remains intact!

Current Solution Attempt The closest solution achieved 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
}

Even with this approach, managing the string literal union type Fruits and Fruit is still necessary. This solution would be ideal if there was a way to programmatically create the string literal union type Fruits.

Answer №1

Discovering the fruit you desire by iterating through Enum values.

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Explore RxJs DistinctUntilChanged for Deep Object Comparison

I have a scenario where I need to avoid redundant computations if the subscription emits the same object. this.stateObject$ .pipe(distinctUntilChanged((obj1, obj2) => JSON.stringify({ obj: obj1 }) === JSON.stringify({ obj: obj2 }))) .subscribe(obj =& ...

Methods for organizing consecutive elements within an array in Javascript/Typescript

Let's explore this collection of objects: [ { key1: "AAA", key2: "BBB" }, { key1: "BBB", key2: "CCC" }, { key1: "CCC", key2: "DD ...

No data found in the subrow of the datasource after the filter has been

I am working with a material table that has expandable rows. Inside these expanded rows, there is another table with the same columns as the main table. Additionally, I have implemented filters in a form so that when the filter values change, I can update ...

Resolving type error issues related to using refs in a React hook

I have implemented a custom hook called useFadeIn import { useRef, useEffect } from 'react'; export const useFadeIn = (delay = 0) => { const elementRef = useRef<HTMLElement>(null); useEffect(() => { if (!elementRef.current) ...

"Unlocking the full potential of Typescript and Redux: Streamlining the use of 'connect' without the need to

I am facing some challenges with typescript and redux-thunk actions. The issue arises when my components heavily rely on react-redux connect to bind action creators. The problem occurs when I create the interface for these redux actions within the compone ...

What could be preventing me from setting a boolean variable within an Observable?

After retrieving data from the Service, I am attempting to hide a specific div element. Below is the HTML code: <progressbar *ngIf="isLoadingBootStockData" [value]="100" type="default"> </progressba ...

Uploading Files with Angular 2 using AJAX and Multipart Requests

I am currently working with Angular 2 and Spring MVC. At the moment, I have an Upload component that sends an AJAX request to the Spring backend and receives a response containing parsed data from a .csv file. export class UploadComponent { uploadFile: f ...

Encountering a 403 error with RXJS when attempting to subscribe to a websocket in Angular

I am currently searching for a resolution to this issue without making any upgrades to Angular or its dependencies, as it could potentially impact other parts of the code base https://i.sstatic.net/Jeb55.png package.json { "name": "angular4", "v ...

Error: Attempting to access 'config' property of undefined variable

I am currently utilizing Vue 3 with Typescript and primevue. After integrating primevue into my application, I encountered the following errors and warnings. The issue arises when I attempt to utilize the primevue 'Menubar' component, however, wh ...

Is it necessary for Vue single file components (.vue files) to use `export default` or is it possible to use named exports instead?

export default may no longer be the recommended way to export modules, as discussed in these resources: After changing my Vue components from this: <script lang="ts"> 'use strict'; import {store} from '../../data/store' ...

What is the most effective method for distributing TypeScript functions that are used by services and span multiple components?

I have a set of TypeScript functions that are currently scattered across components. These functions are being duplicated unnecessarily, and I am looking for a way to centralize them so all components can access them without redundancies. Since these fun ...

Incorporating FormControl Validators within a Child Component in Angular

Having two Angular Components, one is called parent.ts and the other is named child.ts. Parent.ts contains a Form group, while child.ts passes the Form data via CVA to the parent. Now, I am looking to create a reusable child component that can generate c ...

The superclass defines the type of the subclass

There is an abstract typescript class like this: abstract class Abstract { constructor (public parent?: Abstract) { } } Then, two subclasses are defined as follows: class Sub1 extends Abstract { } class Sub2 extends Abstract { } The issue aris ...

Exploring Tailwind's flexibility with custom color schemes

I'm attempting to generate unique hex colors for my React/TypeScript application with Tailwind. Why isn't the background color updating based on the color variable value? Check out my code snippet below: import React, { useState } from &apo ...

Discover the most effective method for identifying duplicate items within an array

I'm currently working with angular4 and facing a challenge of displaying a list containing only unique values. Whenever I access an API, it returns an array from which I have to filter out repeated data. The API will be accessed periodically, and the ...

Tips for preventing repetition of code in multiple entry points in Rollup

My goal is to use rollup to process a group of input files and generate multiple output files in the dist directory that all have some common code shared between them. Below is my current rollup configuration: import path from 'path'; import pat ...

using props as arguments for graphql mutation in react applications

Here is the structure of my code: interface MutationProps{ username: any, Mutation: any } const UseCustomMutation: React.FC<MutationProps> = (props: MutationProps) => { const [myFunction, {data, error}] = useMutation(props.Mutati ...

Transform object properties into key-value objects using Typescript generics

When I receive a sorting object with a columnName and direction, I want to convert it into a key-value object for mongoose sorting. The return values are not matching up and I can't seem to figure out what I'm missing. These are the interfaces ...

A glitch was encountered during the execution of the ionic-app-scripts subprocess

I recently started using Ionic 3 and created an application that I'm trying to convert into an APK. To generate a debug (or testing) android-debug.apk file, I used the following CLI command: ionic cordova build android --prod The pages are declared ...

Having trouble resolving the '@angular/material/typings/' error?

I am currently working on tests for an angular project and encountering errors in these two test files: https://pastebin.com/bttxWtQT https://pastebin.com/7VkirsF3 Whenever I run npm test, I receive the following error message https://pastebin.com/ncTg4 ...