The Ultimate Guide to Converting Enums to Object Types using Typescript

Imagine having an enum declared as follows:

enum CustomerType {
   New = 'new',
   Owner = 'self',
   Loyal = 'subscriber'
}

Utilizing this enum can simplify checks like:

if(customer.type === CustomerType.New)

What is the recommended approach for typing an object where the enum values serve as keys? For instance, let's consider a function named getCustomerType that might produce:

{ 
   new: true,
   self: false,
   subscriber: false
}

Keep in mind that reducing this output to just the true key may not be feasible due to the system's architecture limitations :)

One solution I attempted is as follows:

type CustomerConfig = { [key in CustomerType]: boolean }

Suppose I wish to extract the first true key from this object, the process would look something like this:

export const getCustomer = (obj: CustomerConfig): CustomerType => {
    const customerType = Object.keys(obj).find(x => {
        // Object.keys return `string[]` instead of keyof type https://github.com/microsoft/TypeScript/issues/20853
        return obj[x as keyof CustomerConfig]
    })
    return customerType as CustomerType
}

const tempCustomer = getCustomer({
    'new': true,
    'self': false,
    'subscriber': false
})

console.log(tempCustomer === CustomerType.New)  // true
console.log(tempCustomer === CustomerType.Owner) //false

Is there a more efficient way to achieve this?

Answer №1

Here are some suggestions for improvements:

  • When using the find function on an array, it may return undefined if no matches are found. It's a good idea to add this type and additional checks for better handling.
  • Typescript can sometimes return the wrong type for Object.keys. You can explicitly specify the correct type to Typescript instead.
export const getCustomer = (obj: CustomerConfig): CustomerType | undefined => {
  return (Object.keys(obj) as Array<keyof CustomerConfig>)
     .find(x => obj[x])
}

const tempCustomer = getCustomer({
    'new': true,
    'self': false,
    'subscriber': false
})

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

Navigating through the Angular Upgrade Roadmap: Transitioning from 5.0 to 6

As per the instructions found in this helpful guide, I executed rxjs-5-to-6-migrate -p src/tsconfig.app.json. However, an error is appearing. All previous steps were completed successfully without any issues. Any suggestions on how to resolve this? Please ...

Explanation of Default Export in TypeScript

I recently started learning about JS, TS, and node.js. While exploring https://github.com/santiq/bulletproof-nodejs, I came across a section of code that is a bit confusing to me. I'm hoping someone can help explain a part of the code. In this project ...

The task of mapping an array of objects with nested values using JavaScript is proving to

Attempting to convert an array of objects with nested values in child objects like: const objs = [{ "B": { "value": 1, }, "D": { "value": "45" }, "E": { "value": "234" }, ...

The application is unable to load due to a console error showing that the endpoint is unreachable

Recently, I made an upgrade from Angular 5 to 7 while still keeping rxjs-compat in place. Initially, the application was running smoothly with no issues. However, we eventually decided to remove rxjs-compat and make the necessary changes. This is when we e ...

Utilizing React with Typescript to create JSX text translation files

My task involves translating text stored in a file... ///translations.txt const TEXT: { [x: string]: { [y: string]: string } } = { en: { joinNow: <React.Fragment>Join <b>Now<b/></React.Fragment>, signUp: <React.Fragmen ...

Determining the specific condition that failed in a series of condition checks within a TypeScript script

I am currently trying to determine which specific condition has failed in a set of multiple conditions. If one does fail, I want to identify it. What would be the best solution for achieving this? Here is the code snippet that I am using: const multiCondi ...

Determine the output of a function based on the structure of the input parameter by mapping through a complex nested object

Trying to implement some intricate typing for a project I'm developing, and wondering if it's achievable with TypesScript. The project in question is a form generator based on schemas and promises, using Vue and TS. It handles UI rendering, vali ...

Encountering a 404 error with Angular 6 routing after refreshing the page when using an Nginx proxy

I currently have my angular application running within a docker container, exposed on port 83. Additionally, I have a separate spring-boot rest app running inside another docker container, exposed on port 8083. On the host server, there is an Nginx server ...

angular 6 personalized material icons with ligature assistance

Can I create my own custom material icons with ligature support? Currently, I use svgIcon to get Custom Icons, Is there a way to make custom icons that support ligatures? Here is my current code snippet: app.component.ts import { Component } from &ap ...

Defining the TypeScript interface for the onClick event in ReactJS

If you're looking to dive into React development, the tutorial on reactjs.org is a great place to start. While the tutorial code is in JavaScript, I've been working on converting it to TypeScript. I've successfully translated most of the c ...

Managing return types in functions based on conditions

Recently, I developed a function to map links originating from a CMS. However, there are instances where the link in the CMS is optional. In such cases, I need to return null. On the other hand, when the links are mandatory, having null as a return type is ...

Retrieving object information in the constructor using Angular and Typescript

When attempting to access an object's data within a constructor, it results in an "undefined" object. Even though it functions properly in the ngOnInit() function, the data which is about to be reset is required every time the component is initiated. ...

What is the appropriate data type to specify for the useLoaderData() function, and in what

I'm currently delving into the deep #6 tutorial on NetNinja's react-router, but I'm attempting to implement it using TypeScript. My task involves fetching data from a JSON object, utilizing the useLoaderData() hook, and trying to properly ma ...

Divide a given number of elements within an array of arrays

Presented below is an array: [ { "id": "34285952", "labs": [ { "id": "13399-17", "location": "Gambia", "edge": ["5062-4058-8562-294 ...

The type 'TaskListProps[]' cannot be assigned to type 'TaskListProps'

I'm struggling with handling types in my TypeScript application, especially with the TaskListProps interface. export default interface TaskListProps { tasks: [ { list_id: string; title: string; description: string; status ...

Is there a way to stop observing an Observable or Subject after its first emission while setting up the observer?

Currently, I am in the process of implementing dialogs using Angular 9 and I encountered a scenario where I need to unsubscribe from a Subject after its first emission. Initially, my approach was to use the take(1) or first() operators to transform the Su ...

Issues with Vercel's JavaScript Environment Variables Accessibility

I am encountering an issue trying to access environment variables on Vercel using JavaScript (TypeScript). Despite setting them under /settings/environment-variables, I receive undefined when attempting to access them with process.env.TURSO_DATABASE_URL du ...

Encountering an error when attempting to access undefined property while using a method as a callback

Exploring OOP and angular is new to me. I am currently trying to implement a reusable table with pagination that triggers an API request when the page changes (pagination within the table component). The issue arises when I attempt to access my method usi ...

steps for creating a route with @input

I have created a component that utilizes an HTML attribute. I set it up so that users can specify the route when using this component within another component. However, every time I attempt to define the route value, I encounter a 'No provider for Rou ...

Unit Testing Angular: Passing FormGroupDirective into a Function

I am currently writing unit tests for a function that takes a parameter of type FormGroupDirective. I have been able to test most of the logic, but I'm unsure about what to pass as a parameter when calling the resetForm() function. Here is the code sn ...