What's the best way to determine the type of the enum literally?

I am working with an enum called RadCheck that looks like this:

enum RadCheck {
  blank = 0,
  userDefined = 1,
  macAddress = 2,
}
const H = RadCheck[RadCheck.blank]

Currently, the variable H is being recognized as a string, but I want it to be inferred as "blank" without having to manually cast it. Is there a way to achieve this?

Visit Typescript playground

Answer №1

Reverse mappings in enums currently do not have literal types assigned to them; they are only of type string. There is a feature request open at microsoft/TypeScript#50933 to add support for reverse values with literal types, but as of now, it is not part of the language.


If you need to move forward, you will have to find a workaround, which may involve using a type assertion at some point. You could create a utility type to search for an enum key based on its value type:

type ReverseEnumLookup<T, V> =
  keyof { [K in keyof T as T[K] extends V ? K : never]: 0 }

This method uses key-remapping in a mapped type to filter out keys of T that match the given value type. It operates similarly to KeysMatching discussed in In TypeScript, how to get the keys of an object type whose values are of a given type?. Here's how it works:

type TestA = ReverseEnumLookup<typeof RadCheck, RadCheck.blank>;
// type TestA = "blank"
type TestB = ReverseEnumLookup<typeof RadCheck, RadCheck.macAddress>;
// type TestB = "macAddress"
type TestC = ReverseEnumLookup<typeof RadCheck, 12345>;
// type TestC = never

So you could proceed as follows:

const H = RadCheck[RadCheck.blank] as ReverseEnumLookup<typeof RadCheck, RadCheck.blank>;
// const H: "blank"
console.log(H) // "blank"

However, this might be more cumbersome than helpful. Instead, consider creating a utility function that utilizes this type to reverse any enum (as demonstrated in How to look for a key with value in Typescript Enum?):

function reverseEnumLookup<T extends object, const V extends T[keyof T]>(
  t: T,
  v: V
) {
  const ret = Object.entries(t).find(e => v === e[1]);
  if (ret === undefined) throw new Error("not found");
  return ret[0] as ReverseEnumLookup<T, V>;
}

This approach is likely more user-friendly:

const H = reverseEnumLookup(RadCheck, RadCheck.blank);
// const H: "blank"
console.log(H); // "blank"

You could even simplify reverseEnumLookup() to perform a direct index lookup, but the specific implementation is less important than recognizing that the desired operation is lacking a feature and requires a workaround involving at least one type assertion or similar loosening of types.

Playground link to 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

Retrieving data from array services in Angular using Typescript

I need help retrieving data from an array in my services using a get function. I've tried using the .filter and .find functions, but I'm struggling with the execution and haven't been able to retrieve the data successfully. I know this may b ...

Alter the class based on the incoming string from the rxjs stream

I have a stream that outputs strings, and based on these strings I want to apply certain classes to a specific tag: If the string is "ok", add class "fa-check" If the string is "loading", add classes "fa-spin" and "fa-spinner" If the string is "error", a ...

What is the best way to implement a timeout and subsequently clear it in a React functional component?

Hello there, I am currently working on a functional component in ReactJS and I am facing an issue with implementing a timeout on mouse hover over a menu. The timeout functionality is working fine, but I am struggling to clear this timeout in another funct ...

Protractor encounters an error stating "No element found with specified locator" after attempting to switch to an

I've been attempting to download an embedded PDF from a webpage using Protractor selenium. However, I seem to be stuck when it comes to actually downloading the file as I always encounter the following error: Failed: No element found using locator: ...

Creating an async function in TypeScript to retrieve the coordinates of a particular location is a useful way to streamline the

I am looking to retrieve the coordinates of a location as the output of a function. The coordinates are already assigned within a fetch method, with latitudes stored as coordinates.lat and longitudes stored as coordinates.lng. [Currently, it is returning ...

When utilizing <number | null> or <number | undefined> within computed() or signals(), it may not function properly if the value is 0

I've encountered an issue while implementing signals and computed in my new Angular project. There's a computed value that holds an id, which is initially not set and will be assigned by user interaction. To handle this initial state, I attempte ...

The proper approach for managing downloaded d.ts files from DefinitelyTyped after installation through npm

Visual Studio 2017 Enterprise ASP.NET MVC Application TypeScript 2.5 SDK Source control is in TFS I have opted to use Microsoft's built-in property editor instead of creating a custom tsconfig.config file: https://i.sstatic.net/VgcQO.png To streaml ...

Can an Angular 2 module export an interface?

While attempting to export an interface in a NgModule-declaration, I encountered an error message in my editor (Visual Studio Code) stating: [ts] 'MyInterface' only refers to a type, but is being used as a value here. Below is the code snippet c ...

"Enhance your Vue 3 projects with a dynamic library featuring universal components and full

Currently, I am in the process of developing a Vue 3 component library using Vue 3, Vite, and TypeScript. The unique aspect about this library is that it installs as a plugin and registers all components as global entities. Here is an overview of how this ...

Achieving checkbox values in Typescript: A guide

I need help with capturing the values of checked checkboxes and storing them in a string to use in my API. I want to retrieve the value if a checkbox is unchecked. <div *ngFor="let x of groupesTable"> <input type="checkbox" [(ngModel)] ...

How can the ChangeDetectorRef be leveraged to identify and respond to changes in component state for seamless integration with the material stepper component

While working with the Angular 8 Material Stepper, I am validating form states and setting stepCompleted to true when the conditions pass. You can view a demo of this functionality on Stackblitz: https://stackblitz.com/edit/angular-mat-stepper-demo-with-f ...

Display or conceal columns in reaction to user choices with react-table in React with Typescript

I'm currently using react-table to create a data grid within my application. I have a specific requirement to show/hide columns based on user selection. Is there a way to accomplish this? Essentially, I need to implement a settings icon that, when cl ...

obtain every drop-down choice from Angular 2's selectiongetConfig() function

Within the document, there is a select element as shown below: <select tabindex="1" size="5" name="abc" multiple> <option value>Select a value.</option> <option value>option 1</option> <option value>option 2 ...

Is there a way to defer a for loop in Angular?

In my Angular project, I am working on a sorting visualizer using the chart.js bar chart. Currently, I am focusing on visualizing bubble sort and I want to incorporate a delay in each iteration of the inner loop. I assume you are familiar with the loop s ...

Tips for using the useState hook to modify an array by its index?

I am working on a select component that needs to update values in an array of objects based on the index. Utilizing the hook as follows: const [areas, setAreas] = useState(product.areas); This is how the "areas" array looks: [ 0: {de: "Getraenke", en: ...

Utilize the npm module directly in your codebase

I am seeking guidance on how to import the source code from vue-form-generator in order to make some modifications. As a newcomer to Node and Javascript, I am feeling quite lost. Can someone assist me with the necessary steps? Since my Vue project utilize ...

How to troubleshoot: trying to assign '{ source: string; }' to type 'string' is not valid

I'm encountering an issue that seems like it should have a simple solution, but I can't seem to find any explanations on how to fix it. I'm working with Next.js and Typescript to create a component that displays an image and uses hooks to ma ...

Having trouble utilizing HTML Canvas in the newest release of Angular and TypeScript

After extensive searching on the internet, I have not been able to find any working examples of using HTML canvas in Angular. It seems that changes in syntax in Typescript and Angular's newer versions have rendered all existing solutions obsolete. I ...

Understanding the correct way to map two arrays with boolean values is essential for effective data

My situation involves two lists: accounts and accountsWithSelectedField. I initially mapped accountsWithSelectedField like this: this.accountsWithSelectedField = this.accounts.map(s => ({...s, selected: false})); Subsequently, upon receiving a list of ...

Custom typings for Next-Auth profile

I'm experiencing an issue with TypeScript and Next Auth type definitions. I followed the documentation guidelines to add my custom types to the NextAuth modules, specifically for the Profile interface in the next-auth.d.ts file. It successfully adds t ...