What is the best way to create an array of strings that can include multiple elements from a set of strings?

Exploring different roles for authorization:

['admin', 'manager', 'user']

Is there a way to create a specific type, named Roles, which is essentially a string array ( string[] ) that is limited to only containing values from the list of roles mentioned above? It should also be able to be an empty array.

Edit: Here is my initial attempt at defining this:

type Roles = [] | ['user'] | ['manager'] | ['admin'] | ['user', 'manager'] | ['user', 'admin'] | ['manager', 'admin'] | ['user', 'manager', 'admin']

However, this structure does not allow for:

const roles:Roles = ['admin','user']

Furthermore, if there are 4 roles, it becomes cumbersome as the number of options increase exponentially and it does not support variations in position within the list.

Answer №1

To start, establish a type called Position that can only be 'employee', 'supervisor', or 'manager' as shown below:

type Position = 'employee' | 'supervisor' | 'manager';
type Positions = Set<Position>;
//If there are multiple 'supervisor' positions in the list, Set will eliminate duplicates and keep the first instance
//resulting in a unique set of roles with supervisor role being distinct
const uniquePositionSet: Positions = new Set<Position>(['employee', 'manager', 'supervisor', 'supervisor']); 

Next, define another type that represents a Set containing instances of the Position type.

Answer №2

To simplify your code, consider using an enum to define the possible values and include functions for converting between strings and the custom enum.

For example:

enum UserRole {
    Admin = 'admin',
    Manager = 'manager',
    User = 'user',
}
type UserRoles = UserRole[]

const userRoles: UserRoles = [UserRole.Admin, UserRole.User]

Here is a conversion example (refer to How do I convert a string to enum in TypeScript? for more information):

function convertToRole(name: string): UserRole {
    return name as keyof typeof UserRole
}

const convertedUserRoles: UserRoles = [convertToRole('admin'), convertToRole('user')]
const roleName = UserRole[UserRole.Admin] // 'admin'

Refer to the TypeScript documentation at https://www.typescriptlang.org/docs/handbook/enums.html#string-enums for further details.

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

Utilizing TypeScript Variables within a Jquery Each Iteration

I have a variable named tableIndexNumber that I need to use in different methods. When trying to access this variable, I use "this.tableIndexNumber" and it works fine. However, I face an issue when using it inside a jQuery each loop because the HTML elemen ...

Is your React Native list elements feeling a little too close for comfort?

I'm facing an issue where the items in my list are not properly spaced out and I'm unable to figure out why. I have 3 elements for each letter that should be separated from each other. I suspect that the issue might be related to the fact that th ...

Encountering an Object Type Unknown error while working with Typescript and React

I am currently working on building a chatbox in React using TypeScript and Firebase. Below is the code for my Room and Message components: function ChatRoom() { const messagesRef = firestore.collection('messages'); const query = messagesRef.o ...

Having difficulty transforming ".jsx" to ".tsx" in a Next.js application while working with "getStaticProps"

My application utilizes the Printifull API and performs well with .jsx using the code snippet below: import axios from "axios"; export default function ApiTest(props) { console.log(props); return( <></> ( } export async ...

Issue TS2322: The type 'Observable<any>' cannot be matched with type 'NgIterable<any> | null | undefined'

Encountering an error while attempting to fetch data from the API. See the error image here. export class UserService { baseurl: string = "https://jsonplaceholder.typicode.com/"; constructor(private http: HttpClient) { } listUsers(){ //this ...

Ways to resolve the issue of the missing property 'ganttContainer' on the 'Gantt' type

I encountered an issue while trying to utilize the Gantt chart feature from the Dhtmlx library in TypeScript. The problem seems to stem from an error during the initialization of gantt. How can I go about resolving this? Below is the relevant code snippet: ...

What strategies can I use to address the issue of requiring a type before it has been defined?

Encountered an intriguing challenge. Here are the types I'm working with: export interface QuestionPrimative { question : string; id : string; name : string; formctrl? : string; formgrp? : string; lowEx ...

What is the key to ensuring the content in your canvas adapts to different screen sizes

Greetings! I wanted to extract the values from this specific meta tag: <meta name="viewport" property="viewport" content="width-device-width, initial-scale=1"> To retrieve content from a meta tag using JavaScript, I used the following code snippet: ...

What is the best approach to apply type casting in an *ngFor loop for an array containing a variety of types in Angular?

I am facing a scenario where I have two objects named DeviceA and DeviceB, both belonging to the same parent class called Device. interface Device { shared: string } interface DeviceA extends Device { attributeA: string[] } interface DeviceB extends ...

Step-by-step guide on incorporating HTML into a popover within Angular4

After successfully implementing a hover popover in Angular using PopoverModule from ngx-popover, I now need to modify the content inside the popover. My search led me to this example: <ng-template #popContent>Hello, <b& ...

What is the best way to implement Infinite scroll alongside Virtual scroll in Ionic 3?

Having recently delved into the world of Ionic and Angular, I am encountering some difficulties with implementing Infinite scroll alongside Virtual scroll. Despite pushing data such as images, text, and click functions from TypeScript, only empty Ionic car ...

Facing an issue with the TypeScript error in the Tailwind-Styled-Component Npm package. Any suggestions on how to troub

module.styles.ts File import tw from "tailwind-styled-components"; export const Wrapper = tw.div` bg-green-500 `; export const Link = tw.a` text-blue-500 `; home.jsx File import React from "react"; import { Wrapper, Link } from &qu ...

Exploring Dependency Injection in Angular2: A Comparison of TypeScript Syntax and @Inject Approach

I'm currently working with Angular2 build 2.0.0-alpha.34 and I can't figure out why I'm getting different results from these two code snippets. The only variation is between using @Inject(TitleService) titleService and titleService: TitleSe ...

Angular - Execute function every 30 seconds while considering the duration of the function execution

In my Angular 7 application, I am utilizing RxJS to handle asynchronous operations. My goal is to retrieve a list of items from an API endpoint every 30 seconds. However, there are times when the request may take longer than expected, and I want to ensure ...

What is the reason that setState functions properly when parsing each key separately, but fails when passed as an object?

Currently, I am delving into the world of React and TypeScript, but I have encountered a problem when trying to pass an object with a specific type in order to update the state. For some reason, the state remains unchanged. My approach involves using the ...

Incorporate new class into preexisting modules from external library

I am currently working on expanding Phaser by incorporating a new module called Phaser.Physics.Box2D. While Phaser already utilizes this module internally, it is an additional plugin and I am determined to create my own version. TypeScript is the language ...

Using Rollup alongside @rollup/plugin-babel and Typescript: Anticipated a comma, received a colon instead

I've encountered a problem while working with Rollup 4: [!] RollupError: Expected ',', got ':' (Note that you need plugins to import files that are not JavaScript) src/index.ts (48:19) Although my Babel configuration appears to ...

Is it possible to omit certain fields when using the select function in MikroORM?

When working with nested populate queries in MikroORM with MySQL, I am faced with the challenge of selecting 100 fields while wanting to exclude around 20 fields. It would make more sense to leave out those 20 fields, similar to using db.find().select("- ...

Receiving an error when triggering an onclick event for a checkbox in TypeScript

I am creating checkboxes within a table using TypeScript with the following code: generateTable(): void { var table = document.getElementById("table1") as HTMLTableElement; if (table.childElementCount == 2) { for (var x = 0; x < 2; x++) ...

Angular Error: Unable to access property 'users' on a null value

I am working on a component that takes in data through the @Input() decorator regarding a group. My objective is to generate a new array of objects during the initialization of the component based on the data from the group array. Below is the TypeScript c ...