Best practice in TypeScript for handling an Enum with a switch-case to assign a variable

Here's an issue I'm facing: I have a variable called Difficulty that is an Enum. Within a function, I need to set the configuration DifficultyConfig based on the value of Difficulty. The current solution I have in mind seems overly complicated:

 (insert modified code here) 

I find the Switch case syntax to be clunky for such a straightforward task. In Scala, I would prefer something like this:

 (insert Scala equivalent code here) 

Is there a similar approach in JavaScript?

Answer №1

If there is a difference in reasoning, opt for a switch or an if/else if/else (a bit less wordy) method (more details on this below). If it pertains strictly to data like in your instance, then you could utilize a complexity-to-configuration mapping object:

const difficultyConfigs = {
    [Difficulty.NORMAL]: NormalDifficultyConfig,
    [Difficulty.HARD]: HigherDifficultyConfig,
    [Difficulty.ADVANCED]: HigherDifficultyConfig,
} as const;

You could even define that as

Record<Difficult, DifficultyConfig>
just like this, as highlighted by caTS in the comments:

const difficultyConfigs: Record<Difficult, DifficultyConfig> = {
//                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    [Difficulty.NORMAL]: NormalDifficultyConfig,
    [Difficulty.HARD]: HigherDifficultyConfig,
    [Difficulty.ADVANCED]: HigherDifficultyConfig,
} as const;

More information on that shortly, but either way, the function becomes quite simple:

function createApp(difficulty: Difficulty) {
    let difficultyConfig = difficultyConfigs[difficulty];
    
    return new App({
        difficultyConfig
    });
}

Playground links: Without Record | With Record (I also corrected some possible typos/editing mistakes in the original code.)

This approach has the added benefit that if you introduce a new Difficulty but overlook including it in difficultyConfigs, you will receive a useful compile-time error when attempting to use it. I have simulated such an error here by adding a MEDIUM difficulty but failing to update the function.

Even for logic, you can apply the same idea to construct a dispatch object:

const difficultyConfigs: Record<Difficulty, () => DifficultyConfig> = {
    [Difficulty.NORMAL]: () => { /*...build and return NORMAL config...*/ },
    [Difficulty.HARD]: () => { /*...build and return HARD config...*/ },,
    [Difficulty.ADVANCED]: () => { /*...build and return ADVANCED config...*/ },,
} as const;
// ...
const difficultyConfig = difficultyConfigs[difficulty]();

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

Tips on displaying a particular JSON attribute?

After starting with a JSON string, attempting to convert it into a JSON object and then trying to print a specific field (such as firstName), I am getting undefined. What could be the issue here? Thank you for your help! var string = '{"firstName ...

Is there a way to dynamically switch between AngularJS modules based on a configuration change?

Understanding the inner workings of Dependency Injection with AngularJS modules has sparked an idea in my mind. I thought about leveraging this concept to switch between different modules based on the environment of the application. For instance, I aim to ...

Switch up the position of an element every time the page is refreshed

I have a webpage containing 5 images, each measuring 48px by 48px. I would like these images to be displayed in random positions on the page every time it is loaded. While I am aware that I will need to use CSS and JavaScript for this task (specifically f ...

PrismaClient is currently incompatible with this browser environment and has been optimized for use in an unknown browser when performing updates

While attempting to update a single field in my database using server-actions and tanstackQuery, I encountered the following error message: Error: PrismaClient is unable to run in this browser environment, or has been bundled for the browser (running in ...

I am attempting to incorporate a List View within a Scroll View, but they are simply not cooperating. My goal is to display a collection of items with additional text placed at the bottom

This is how it should appear: item item item item additional text here I am trying to create a layout where the list is in List View for benefits like virtual scrolling, but the entire layout needs to be within a Scroll View. I want to be able to con ...

Error in Internet Explorer when attempting to close a Fancybox iframe that plays a YouTube video

Even the FancyApps page itself contains the error mentioned below. If you visit using Internet Explorer 9, for example, follow these steps: Go to Internet Options > Advanced > Disable script debugging (Internet Explorer). Then click on the YouTube ( ...

Tips for utilizing the json_encode function with an array

I am trying to extract specific data from an object created using the json_encode function in PHP. while($locations=$req->fetch()){ $t = $locations->titre; $la = $locations->latitude; $lo = $locations->longitude; $typ = $lo ...

Displaying PHP output within a JavaScript expression

Let's dive into a scenario involving a basic HTML document and some JavaScript that's loaded within it: <!-- doc.html --> <!doctype html> <html lang="en"> <head> <script type="text/javascript" src=" ...

Using Jest or Mocha alongside Vue: Uncaught SyntaxError: Cannot use import statement outside a module

Update: This post has undergone multiple edits, please refer to this new Stackoverflow post for a clearer explanation of the issue: SyntaxError: Cannot use import statement outside a module when following vue-test-utils official tutorial I have been searc ...

Just getting started with JavaScript and running into trouble creating an array of image objects using an array of strings

I am struggling to accurately describe my issue, making it difficult to find a solution. I have an array called tempData generated from a text file that I want to reference with variables of the same name as the strings in the array. var red = new Image ...

End of ImageButton tag

I am currently working on this code : <div runat="server" class="slide"> <img src="images/picto_detail.gif" onclick='<%# Eval("CampagneRappelId","hideshow(\"details{0}\")")%>' /> <div id='details<%# Eval("C ...

Leverage SVGs imported directly from the node_modules directory

Our architecture has been modularized by creating a node_module that contains all SVG files. Using the following code works perfectly: <q-icon> <svg> <use xlink:href="~svgmodule/svgs/icons.svg#addicon"></use> </svg> ...

Error: Unable to retrieve data due to null value (property 'detail' is undefined)

When I use useEffect() function to set the document title to 'View Orders | Bothub' and fetch data from a backend URL, I encounter an error. The error message reads: Unhandled Rejection (TypeError): Cannot read properties of null (reading 'd ...

How can you transform the outcome of a TYPO3 repository search into a JSON format?

Is it possible to convert the outcome of a "findAll()" function on a Repository into a JSON object, make changes to specific properties in JavaScript, and then send it back to the Action, converting it again for use by the Action to persist it in the datab ...

Getting the length of child elements in Angular using ngFor loop

Can anyone help me figure out how to check the length of a child element in my Angular *ngFor loop? I am fetching data from a real-time firebase database. What am I doing wrong? Here is the code snippet I am using: <div *ngFor="let event of events"> ...

Oops! A JSON parsing error occurred due to the presence of an unexpected token '}'

I encountered an issue while trying to develop a registration route using passportjs. When sending a request via Postman, I received the following error message: SyntaxError: Unexpected token } in JSON at position 119    at JS ...

Ways to transfer a v-model from the parent component to a template

I'm currently in the process of designing the user interface for a search page and I want to utilize components to help with code reusability. However, I am facing a challenge in figuring out how to pass the model of the page to the search component. ...

The addition of days is producing an incorrect result

When extracting the date from FullCalendar and attempting to edit it, I noticed that moment.js seems to overwrite all previously saved dates. Here is an example of what's happening: var date_start = $calendar.fullCalendar('getView').start.t ...

Utilizing a Map with Angular's ngFor

Currently, I am working with Ionic 3, which utilizes Angular and TypeScript. My goal is to use ngFor with a Map type in my project. Below is what I have implemented so far: interface IShared_Position { lat: number; lng: number; time: number; ...

Is there a way to sort through a JSON object using JavaScript?

I have a JSON string that looks like this: { "Animal":{ "Cat":20, "Dog":10, "Fish":5 }, "Food":{ "Pizza":500, "Burger":200, "Salad" ...