Unexpected issue with resolving a Typescript string enum from a string value

As I was working on my project, I had an enumeration set up like this

export enum RootPage {
  HOME = <any>'HomePage',
  LOGIN = <any>'LoginPage',
  TEST01 = <any>'Test01Page',
  LAUNCHPAD = <any>'LaunchpadPage',
  JOBS = <any>'JobsPage',
  MACHINES =<any>'MachinesPage',
  GVARS =<any>'GvarsPage',
  RESOURCES=<any>'ResourcesPage',
  CONFIGURATION=<any>'ConfigurationPage', 
  TABS=<any>'TabsPage'
};

Initially, I believed that I could simply do the following:

constructor(
   private menuitemsService:MenuitemsService
) {}
let pageString = 'HomePage';
let rp:RootPage = RootPage[pageString];
let pi:PageInterface = this.menuitemsService.getPagebyRoot(rp)

When it came to the MenuItemsService:

getPagebyRoot(rootPage:RootPage): PageInterface {
  ...
}

However, the issue arose when 'MenuItemService.getPagebyRoot()' interpreted rp as HOME instead of HomePage.

Thus, I had to create a utility method in MenuItemService containing a cumbersome switch statement.

 getRootPageFromString(name:string):RootPage {
    switch (name) {
        case RootPage.HOME.toString():
            return RootPage.HOME;
        case RootPage.LOGIN.toString():
            return RootPage.LOGIN;
        case RootPage.TEST01.toString():
            return RootPage.TEST01;
        case RootPage.LAUNCHPAD.toString():
            return RootPage.LAUNCHPAD;
        case RootPage.JOBS.toString():
            return RootPage.JOBS;
        case RootPage.MACHINES.toString():
            return RootPage.MACHINES;
        case RootPage.GVARS.toString():
            return RootPage.GVARS;
        case RootPage.RESOURCES.toString():
            return RootPage.RESOURCES;
        case RootPage.CONFIGURATION.toString():
            return RootPage.CONFIGURATION;
        case RootPage.TABS.toString():
            return RootPage.TABS;
    }

Eventually, I opted to replace the line in my code with:

let rp:RootPage = this.menuItemService.getRootPageFromString(pageString);

There must be a more straightforward solution.

It was frustrating that I had to resort to this workaround.

Have others encountered similar challenges?

Or discovered a more elegant resolution?

Update:

I have shared my own solution to the problem. The issue stemmed from using TypeScript 2.3.4 instead of 2.4+

Answer №1

When enums are created in typescript, it results in an object structured like this:

TypeScript:

enum RootPage {
  HOME = <any>'HomePage',
  LOGIN = <any>'LoginPage'
}

JavaScript:

RootPage = {
  "HOME": "HomePage",
  "LOGIN": "LoginPage",
  "LoginPage": "LOGIN",
  "HomePage": "HOME"
}

By accessing a property from this enum/object, you can retrieve the corresponding value or key:

Console.log(RootPage["HOME"]);     // HomePage
Console.log(RootPage["HomePage"]); // HOME

This concept simplifies the process - if you have the key, you can obtain the value, and if you have the value, you can retrieve the key. No need for extensive case statements. The necessary information is already available.

Answer №2

After some investigation, I discovered that the issue was specific to the version of Typescript I had installed.

It appears that the problem exists in version 2.3.4, but is resolved in version 2.4 and later. More information can be found here.

The error message I received was:

'Type 'string' is not assignable to type 'RootPage', when attempting to execute the following code:

let pageString = 'HomePage'; 
let rp:RootPage = RootPage[RootPage[pageString]];

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

Issue: Module '@nrwl/workspace/src/utilities/perf-logging' not found

I attempted to run an Angular project using nxMonorepo and made sure to install all the necessary node modules. However, when I tried running the command "nx migrate --run-migrations" in my directory PS C:\Users\Dell\Desktop\MEANAPP&bso ...

Utilize an array as the response model in Amazon API Gateway using the AWS CDK

I am currently in the process of developing a TypeScript AWS CDK to set up an API Gateway along with its own Swagger documentation. One of the requirements is to create a simple endpoint that returns a list of "Supplier", but I am facing challenges in spec ...

An issue has been identified in the node_modules/xterm/typings/xterm.d.ts file at line 10, causing an error with code TS1084. The 'reference' directive syntax used

In my project, I have integrated xterm into Angular5. However, I am encountering an error when trying to run the application. Upon executing ng serve, I am facing the following error: ERROR in node_modules/xterm/typings/xterm.d.ts(10,1): error TS1084: In ...

"Troubleshooting alert: Encounter an error message saying 'process is not defined' when attempting to load the grpc package using proto-loader and grpc-js within a

Looking for help with integrating a typescript Vue.js component that needs to make a grpc call. The proto file can be found here: https://github.com/floydjones1/ts-node-grpc/blob/main/proto/random.proto Here is the component.vue code snippet: <script ...

Can you share the appropriate tsconfig.json configuration for a service worker implementation?

Simply put: TypeScript's lib: ['DOM'] does not incorporate Service Worker types, despite @types/service_worker_api indicating otherwise. I have a functional TypeScript service worker. The only issue is that I need to use // @ts-nocheck at t ...

Challenge when providing particular strings in Typescript

Something seems to be wrong with the str variable on line number 15. I would have expected the Typescript compiler to understand that str will only ever have the values 'foo' or 'bar' import { useEffect } from 'react' type Ty ...

Is there a specific type that is narrower in scope when based on a string parameter?

tgmlDoc.createElement(tagName) typically returns objects of type any. I am looking to refine the return type in the function below in order to simplify the rest of my code. Is there a way to accomplish this? My attempt is shown below, but unfortunately, ...

Leverage the nativeElement property within two separate components

Encountering an error in the autocomplete feature for Angular Maps (AGM), which reads: ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'nativeElement' of undefined TypeError: Cannot read property 'nativeElement' of ...

Creating a personalized event using typescript

I need help with properly defining the schema for an EventObject, specifically what should be included within the "extendedProps" key. Currently, my schema looks like this: interface ICustomExtendedProps { privateNote?: string; publicNote?: string; ...

Utilizing Angular 2 alongside ngrx/store for seamless updates to specific properties within the state object without disrupting the entire structure

I am facing an issue where I need to update a property of a state object without creating a new object. Is there a way to add or update a single property without replacing the entire object? Below is the reducer code: const initialState = { all: [], ...

Tips for waiting for an observable loop

When using my application, the process involves uploading a series of images in order to retrieve the file IDs from the system. Once these IDs are obtained, the object can then be uploaded. async uploadFiles(token: string):Promise<number[]> { let ...

Getting a multidimensional array from JSON in Typescript: A step-by-step guide

Below is a sample of a JSON array containing information about cars. var cars = { "cars": { "john": [], "alex": [ "ford" ], "hilton": [], "martin ...

Looking to substitute the <mark> element within a string with the text enclosed in the tag using JavaScript

In need of help with replacing tags inside a string using JavaScript. I want to remove the start and end tags, while keeping the content intact. For example, if my input string is: <div class="active"><mark class="active-search-position">The ...

Tips for compacting JSON in Typescript

I have encountered a challenge in my coding where we are dealing with quite large data objects. I am exploring the possibility of compressing these data objects to reduce payload size. For instance, if our input json size is 2 MB, can it be compressed to a ...

Printing a string in C can sometimes be tricky as the string may not automatically display

There seems to be an issue with formatting an ASCII-Art style string using strtok. Surprisingly, when I execute my program through my IDE, the string, which is in hexadecimal form, is being printed without any backslashes. However, when I try to run it in ...

Prohibit the Use of Indexable Types in TypeScript

I have been trying to locate a tslint rule in the tslint.yml file that can identify and flag any usage of Indexable Types (such as { [key: string] : string }) in favor of TypeScript Records (e.g. Record<string, string>). However, I haven't had a ...

Troubleshooting Python float to integer conversion issues

I need some help understanding this confusing code snippet: >>> 52920*(15303855351918+15303855298999)/2.0 == 809880023823263820 False >>> 52920*(15303855351918+15303855298999)/2.0 == 809880023823263820.0 True >>> (52920*(1530385 ...

Allowing the use of a string as a parameter in a Typescript constructor

Currently, I am utilizing TypeScript to create a constructor for a model within Angular. One of the attributes in the model is configured as an enum with specific string values. Everything functions well if an enum value is passed to the constructor. The i ...

Error encountered when attempting to pass i18next instance to I18nextProvider

Issue: Error message: Type 'Promise' is missing certain properties from type 'i18n': t, init, loadResources, use, and more.ts(2740) index.d.ts(344, 3): The expected type is derived from the property 'i18n' declared within ty ...

What could be causing the Typescript error when utilizing useContext in combination with React?

I am currently working on creating a Context using useContext with TypeScript. I have encapsulated a function in a separate file named MovieDetailProvider.tsx and included it as a wrapper in my App.tsx file. import { Context, MovieObject } from '../in ...