Using Typescript to map a string to an enum

Having trouble mapping a string to an enum and receiving the error message

TypeError: Cannot convert undefined value to object

export enum CallErrorType {
  UNAUTHENTICATED,
}

const handler: {
  [key in CallErrorType]: (message: string) => void;
} = {
  [CallErrorType.UNAUTHENTICATED]: message => {
    console.log('----> Error UNAUTHENTICATED', message);
  },
};

const CallErrorTypeHandler = (errorCode: string, message: string) => {
  console.log({errorCode});

  const mapped =
    CallErrorType[errorCode as keyof typeof CallErrorType];

  if (mapped !== undefined) {
    return handler[mapped](message);
  } else {
    console.error('Invalid error string:', errorCode);
  }
};

Looking for guidance on my approach.


tsconfig (React Native)

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "React Native",
  "_version": "3.0.2",
  "compilerOptions": {
    "target": "esnext",
    "module": "commonjs",
    "types": ["react-native", "jest"],
    "lib": [
      "es2019",
      "es2020.bigint",
      "es2020.date",
      "es2020.number",
      "es2020.promise",
      "es2020.string",
      "es2020.symbol.wellknown",
      "es2021.promise",
      "es2021.string",
      "es2021.weakref",
      "es2022.array",
      "es2022.object",
      "es2022.string"
    ],
    "allowJs": true,
    "jsx": "react-native",
    "noEmit": true,
    "isolatedModules": true,
    "strict": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": false,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "exclude": [
    "node_modules",
    "babel.config.js",
    "metro.config.js",
    "jest.config.js"
  ]
}

Encountering another issue now:

TypeError: 0, _$$_REQUIRE(_dependencyMap[3](...)rror").CallErrorTypeHandler is not a function (it is undefined)

Answer №1

When TypeScript is used, it defaults to number-based mapping.

The issue arises with how TypeScript handles enum mapping based on numbers. When TypeScript compiles an enum, it creates an object that contains mappings for both numbers to strings and strings to numbers for the enum values. For example, for the CallErrorType enum, the resulting object will look like this:

{
  0: "UNAUTHENTICATED",
  "UNAUTHENTICATED": 0
}

Therefore, when you try to access a value using CallErrorType[errorCode as keyof typeof CallErrorType], you are attempting to retrieve the value of the key named after the string in errorCode. If the string is not found, it will return undefined.

The only solution is to define the enum like this:

export enum CallErrorType {
  UNAUTHENTICATED = "UNAUTHENTICATED",
}

const handler: {
  [key in CallErrorType]: (message: string) => void;
} = {
  [CallErrorType.UNAUTHENTICATED]: message => {
    console.log('----> Error UNAUTHENTICATED', message);
  },
};

const CallErrorTypeHandler = (errorCode: string, message: string) => {
  console.log({errorCode});

  const mapped = CallErrorType[errorCode as keyof typeof CallErrorType];

  if (mapped && typeof mapped === 'string') { // Check if it's a string
    return handler[mapped](message);
  } else {
    console.error('Invalid error string:', errorCode);
  }
};

Some Notes 📝:

-Instead of just checking if mapped !== undefined, it is advisable to also ensure that the mapped value is not a string (i.e., verify that it is a number).

-For clarity, consider using a string-based enum. This can help avoid any potential ambiguities in the code.

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

Comparing Two Items between Two Arrays

I have a scenario where I need to compare values in two arrays by running a condition. The data is pulled from a spreadsheet, and if the condition is met, I want to copy the respective data. For instance, I aim to compare two cells within a spreadsheet - ...

How to update a deeply nested object using a single function in a React component

I have a specific object that requires altering the Ethereum value, for instance; const [reportData, setReportData] = useState({ nameOrganization: "test5", socialMedia: "test", country: "aa", discord: "test", ...

An issue occurs with the scope of a variable during the compilation of Relay Modern code, resulting in an

I have created the following simple Relay Modern code snippet: import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { QueryRenderer, graphql } from 'react-relay' import environment f ...

Function for calling a CSS callback with jQuery

I am currently working on enhancing my search bar using jQuery, and I am also looking to hide the navigation links. Here is a snippet of the jQuery code I have been using. The code functions properly when focused. $(".searchBox input").focus(function(){ ...

Is there a way to see the countdown timers in Angular 7?

Is there a way for me to view my timer's countdown as it starts? I have attempted to bind it to a variable, but all I see is [object Object]: setTime(time) { if (this.settime >= 5 ) { this.currentTime = time; this.alerttime = thi ...

Presentation of information with loading and error scenarios

How can we effectively display data in an Angular view, considering loading state and error handling? Imagine we are fetching a set of documents from our backend and need to present them in an Angular view. We want to address three possible scenarios by p ...

Creating a nested array within each parent array and transferring values in JavaScript

I'm currently facing a situation where I need to insert new array objects named "timeSeriesData" and "units" inside each parent array object, and I also have to copy the values from the parent object into the "timeSeriesData". Any assistance on this w ...

Error message: Angular 12 - Event emitter variable is not defined

I'm currently diving into Angular, specifically working with version 12.0.1 and TypeScript 4.3.4. I'm stumped as to why my event emitter is showing up as undefined. Any suggestions or insights? Here's the error message that keeps popping up ...

Initiate the printing process by executing the window.print() function. As the document is being

Here's the code snippet : <body> <div class="headerCont noprint"> <div class="headerHold"> <div class="logoCont"><img src="images/logo.jpg" width="104" height="74" alt="Logo"> ...

Fade effect on vectorial HTML map with Javascript (mouseover)

I am trying to add a fade in and fade out effect to my image switching function, but I have not been able to adapt other fade methods into mine successfully. Do you have any suggestions on how I can achieve this? Here is an example of what I currently ha ...

Ways to verify if a firebase timestamp surpasses the present date

Would you help me with comparing a timestamp field with the current date using JavaScript? This is what I have tried so far: // Initialize an empty array to store documents let myDocs = []; // Call the getDocs function and handle the response await getDo ...

Is there a way to adjust the navigator locale on a mobile device?

I'm currently testing out a utility function I created for displaying timestamps in a chat. My goal is to make it accessible worldwide and have it dynamically adjust based on the user's language settings. However, I've run into some issues ...

Enhancing ChoicePrompt with ListStyle.heroCard: Adding Personalized Data

I have developed a custom ChoicePrompt with the unique style of ListStyle.heroCard: import {ChoicePrompt, ListStyle} from 'botbuilder-dialogs'; import {PromptValidator} from 'botbuilder-dialogs/src/prompts/prompt'; import {FoundChoice} ...

Sending information to a single component among several

I'm developing a custom DownloadButton component in VueJS that features an animation when clicked and stops animating once the download is complete. The DownloadButton will be utilized within a table where it's replicated multiple times. I intend ...

Tips for ensuring the angular FormArray is properly validated within mat-step by utilizing [stepControl] for every mat-step

When using Angular Material stepper, we can easily bind form controls with form groups like [stepControl]="myFormGroup". But how do we bind a FormArray inside a formGroup? Constructor constructor(private _fb: FormBuilder){} FormArray inside For ...

Reading properties of undefined in React is not possible. The log method only functions on objects

I'm currently facing an issue while developing a weather website using the weatherapi. When I try to access properties deeper than the initial object of location, like the city name, it throws an error saying "cannot read properties of undefined." Int ...

Using Next-Image Relative Paths can lead to 404 errors when being indexed by web crawlers

I have implemented next-image in my project, and all the images are hosted on Cloudinary. The images display correctly, but when I run a website analysis using tools like Screaming Frog, I receive numerous 404 errors. This is because the tools are looking ...

Guide on emphasizing a div when the page's validity is not true

Is there a way to highlight a specific div when the page.isvalid=false? I can display the error message on page load, but struggling to highlight the required control. I have a JavaScript function that applies an error class to the div, which works fine w ...

send the value of a variable from a child component to its parent

I have created a typeahead component within a form component and I am trying to pass the value of the v-model from the child component to its parent. Specifically, I want to take the query model from the typeahead component and place it in the company mode ...

The process of integrating a Loader in Javascript

I am in need of a simple "page loading" animation while my photo is being uploaded. Unfortunately, when I tried using the "blockUI" JavaScript for this purpose, it didn't seem to work with my form. For uploading the image, I have employed a div as a ...