Utilize TypeScript to retrieve the enumeration values as a parameter through a method that employs a generic enum type

Is there a way to retrieve all values of an Enum (specified as a parameter or generic) and return them in a list? Additionally, if the user has a specific role, I only need to retrieve certain Enum values provided as a parameter.

I had the idea of grouping the two parameters as a tuple since they are either both given or neither at all.
My initial implementation would be something like this:

getItemsBasedOnRole<T extends { [s: number]: string }>(...[role, items]?: [UserRole, T[]]) : string[]
{
    const allValues = Object.values(T);
    if (role && items) // if tuple parameter exists
        if (this.securityService.getUser.role === role)
            return items;

    return allValues;
}

const result = getItemsBasedOnRole<MyEnum>([ClientRole], [MyEnum.Value1, MyEnum.Value3]);
// returns [MyEnum.Value1, MyEnum.Value3]

const result = getItemsBasedOnRole<MyEnum>();
// returns [MyEnum.Value1, MyEnum.Value2, MyEnum.Value3]


export enum MyEnum{
    Value1 = 'Value1',
    Value2 = 'Value2',
    Value3 = 'Value3',
}

There are some issues with Typescript:

  • T extends enum is not valid.
    Resolution: Replaced with
    T extends { [s: number]: string }
  • Object.values(T) requires a value but T is a type.
    I thought about adding a parameter enumValue: T, but when calling the method, I couldn't pass just MyEnum; it needed to be MyEnum.ValueX.
    No solution found for this yet.
  • [role, items]? optional tuple is not recognized.
    No solution found for this issue either.

In my latest attempt, I tried to address the problems mentioned above:

getItemsBasedOnRole<T extends { [s: number]: string }>(enumValue: T, ...[role, items]: [UserRole, T[]]): string[]

The challenges I encountered mainly involve types and function definitions while my goal remains to create a dynamic list. Any suggestions or alternative approaches are welcome: whether that's splitting functions, utilizing parameters instead of generic types, etc.

Answer №1

Instead of utilizing enums, I recommend using constant objects as they are more consistent and easier to handle. To ensure type safety and prevent the object's type from being widened, it is crucial to apply const assertion. Additionally, we can employ the satisfies operator:

export const MyEnum = {
  Value1: 'Value1',
  Value2: 'Value2',
  Value3: 'Value3',
} as const satisfies Record<string, string>

Since our enum is of type Record<string, string>, we will adjust the generic argument constraint accordingly:

declare function getItemsBasedOnRole<T extends Record<string, string>>(obj: T, ...args:[something]) {}

To access all values within the object, we will use indexed access: T[keyof T] will provide the union of all values:

declare function getItemsBasedOnRole<T extends Record<string, string>>(obj: T, ...args: [role?: UserRole, values?: T[keyof T][]]): string[]

Example of Usage:

getItemsBasedOnRole(MyEnum, 'role', ['Value1', 'Value2'])

playground

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

What is the best way to restrict the suggested values in a property depending on the value of another property?

I'm working on creating a third interface that depends on the value of properties from two other interfaces, while also introducing a unique third property. I've chosen not to extend the third property from the first two interfaces as it may not ...

Discovering duplicates for properties within an array of objects in React.js and assigning a sequential number to that specific field

I am working with an array of objects where each object contains information like this: const myArr=[{name:"john",id:1}{name:"john",id:2}{name:"mary",id:3}] In the first 2 elements, the "name" property has duplicates with the value "john". How can I updat ...

What is the reason TypeScript does not display an error when assigning a primitive string to an object String?

From my understanding in TypeScript, string is considered as a primitive type while String is an object. Let's take a look at the code snippet below: let s: string = new String("foo"); // ERROR let S: String = "foo"; // OK It's interesting to ...

What is the best approach for testing the TypeScript code below?

Testing the following code has been requested, although I am not familiar with it. import AWS from 'aws-sdk'; import db from './db'; async function uploadUserInfo(userID: number) { const user = db.findByPk(userID); if(!user) throw ...

Compilation error occurred when running Angular with mat-form: ngcc encountered an issue while processing [email protected]

Currently dealing with a compile error in a small mat-form example that I created. Unfortunately, I am unable to pinpoint the exact issue causing this error. If you have a moment, please take a look at the code here: https://stackblitz.com/edit/angular-iv ...

What is the primary purpose of the index.d.ts file in Typescript?

There are some projects that include all types declarations within the index.d.ts file. This eliminates the need for programmers to explicitly import types from other files. import { TheType } from './somefile.ts' Is this the proper way to use ...

Arranging arrangements in javascript

I am dealing with objects that contain the fields id and position. const items = [{id: 11, position: 1}, {id: 12, position: 2}, {id: 13, position: 3}, {id: 14, position: 4}, {id: 15, position: 5}, {id: 16, position: 6}]; These objects represent folders st ...

Using the useContext hook across multiple files without needing to export it

I am working on a React app that has multiple states being managed function App(){ const [activeChoice, setActiveChoice] = useState("flights"); const [overlay, setOverlay] = useState(false); const [airports, setAirports] = useState([]); const [loading, ...

typeorm migration:generate - Oops! Could not access the file

When attempting to create a Type ORM migration file using the typeorm migration:generate InitialSetup -d ormconfig.ts command, I encountered an error: Error: Unable to open file: "C:\_work\template-db\ormconfig.ts". Cannot use impo ...

Updating the default value for react-i18next (stored in localstorage)

When utilizing a backend and language detector, an issue arises: The localstorage contains the key I18nextLng with the value en-US. How can we set the default value to be I18nextLng with the value En? init and other settings are as per the default docume ...

Determining When to Activate Button Based on Angular - Verifying That All Choices Have Been Ch

This quiz application requires the user to choose options before proceeding to the next page, with the next button being disabled by default. Once all options are chosen, the next button should become enabled. NOTE: Although the functionality for selecti ...

I am having trouble getting debugging with source maps to work in VSCode and Browserify

I'm currently experiencing an issue with setting breakpoints in Chrome using VSCode, especially when working with TypeScript and Browserify. Oddly enough, if I open Chrome separately and manually refresh the page, the source maps load correctly and I ...

Encountering error "module fibers/future not found" while creating a meteor method in typescript

While working on a Meteor method for async function in my project that combines Meteor with Angular2 using Typescript ES6, I encountered an error. The issue is related to a sync problem in the insert query when inserting data with the same name. To resolve ...

Unexpected behavior observed with Angular Toggle Button functionality

Having trouble implementing toggle functionality in Angular where different text is displayed when a button is toggled. I keep getting an error in my code, can anyone assist? See the code below: HTML <tr> <td>Otto</td> <td> ...

A guide on transitioning from using require imports to implementing ES6 imports with the concept of currying

Currently in the process of migrating a Node/Express server to TypeScript. I have been using currying to minimize import statements, but now want to switch to ES6 import syntax. How can I translate these imports to ES6? const app = require("express")(); ...

I am currently working to resolve this particular wildcard issue with the help of TypeScript

I've been working on solving the wildcard problem with TypeScript, but I'm running into issues with some of the test cases I've created. Here's a brief overview of how the code operates: A balanced string is one where each character ap ...

Having trouble importing a variable from a precompiled library in TypeScript JavaScript

Here is the content of my package.json file: { "name": "deep-playground-prototype", "version": "2016.3.10", "description": "", "private": true, "scripts": { "clean": "rimraf dist", "start": "npm run serve-watch", "prep": "browserify ...

crafting connections in 3D using TypeORM (ORM)

I attempted to construct a database schema involving users, groups, documents, and permissions. Users can be part of multiple groups Groups can have multiple users Users can possess permissions for documents Groups can have permissions for documents Perm ...

Utilizing TypeScript 3.1: Easier Array Indexing with Enums in Strict Mode

Enabling TypeScript "strict" mode with "noImplicitAny" causes this code to fail compilation. I am looking for guidance on how to properly declare and use Arrays indexed by Enum values. namespace CommandLineParser { enum States { sNoWhere, sSwitchValu ...

Unlocking the power of URL manipulation in Fastify using Node.js

I'm attempting to retrieve specific parts of the URL from a Fastify server. For instance, the URL looks like this: http://localhost:300/query_tile/10/544/336 Within the Fastify server, I need the values for z/x/y. I've attempted the following ...