Combining enum values to create a new data type

Exploring the implementation of type safety in a particular situation. Let’s consider the following:

const enum Color {
  red = 'red',
  blue = 'blue',
}

const enum Shape {
  rectangle = 'rectangle',
  square = 'square',
  circle = 'circle'
}

Is there a way to create a type that can accept values from either of these enums?

Here's what has been attempted:

type Characteristics =
  | `${Color}`
  | `${Shape}`

const characteristic: Characteristics[] = ['circle', 'red']; // currently does not fail as intended

However, the requirements were not fully met as the array was able to take any of the enum values.

The desired outcome is:

const char1: Characteristics[] = ['circle', 'square']; // correct
const char2: Characteristics[] = ['circle', 'red']; // should fail
const char3: Characteristics[] = []; // should fail
const char4: Characteristics[] = ['test', 'red', 'blue']; // should fail

Answer №1

Employ a Union Type

(keyof typeof Color)[] | (keyof typeof Shape)[]
to define an array type containing items that are either exclusively of type Color or solely of type Shape.

To guarantee that the array contains at least one value, declare a Tuple Type with a predefined initial item and an expanded array on the second index.

const enum Color {
  red = "red",
  blue = "blue",
}

const enum Shape {
  rectangle = "rectangle",
  square = "square",
  circle = "circle",
}

type Colors = keyof typeof Color;
type Shapes = keyof typeof Shape;

type Characteristics = [Colors, ...Colors[]] | [Shapes, ...Shapes[]];

let char: Characteristics;

char = ["circle", "square"]; // valid
char = ["red", "blue"]; // valid
char = ["circle", "red"]; // invalid
char = ["circle", "red"]; // invalid
char = []; // invalid
char = ["test", "red", "blue"]; // invalid

TypeScript Playground

Answer №2

Looking to create a unique array type in Typescript? Check out this answer: Defining a non empty array type in Typescript

Consider the following solution:

type NonEmptyArray<T> = [T, ...T[]];
type Categories = NonEmptyArray<Genre>|NonEmptyArray<Length>;

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

Subscribing to ngrx store triggers multiple emissions

Currently, I have an app with a ngrx store set up. I am experiencing an issue where, upon clicking a button, the function that fetches data from the store returns multiple copies of the data. Upon subsequent clicks, the number of returned copies grows expo ...

What is the best way to implement the useCallback hook in Svelte?

When utilizing the useCallback hook in React, my code block appears like this. However, I am now looking to use the same function in Svelte but want to incorporate it within a useCallback hook. Are there any alternatives for achieving this in Svelte? con ...

Monitor changes in a dynamic child component using Angular fire and TypeScript only (no HTML)

Currently, I am developing a component using TypeScript and passing inputs to my child component from there. In the parent TypeScript file: this.childComponent = this.viewContainerRef.createComponent(this.data.body).instance; this.childComponent['chi ...

Having Trouble Adding Details to a New Cart for a User in Angular and MongoDB - What's Going On?

After working on an E-Commerce site for a while, I hit a roadblock. Despite taking a break and coming back with determination, I can't seem to resolve the issue at hand. The application features registration, login, product search, and a popup window ...

Updating the useState() function in React when the value changes can be done by utilizing the

I'm struggling to update the count value in my React project. Within my dynamic set, I aim to display the size of the set whenever it changes! My goal is to continuously update the count variable to match ratedSet.size whenever the set's size c ...

Errors in TypeScript are being brought up by using if-else statements inside a loop

I am currently working on a function to retrieve referral codes from users. The user inputs a code, which is then checked against the database to see if it exists or not If the code provided matches the current user's code, it should not be accept ...

Leveraging the power of APIs to bring in the Chicago Art Institute into a React TypeScript

Struggling to import a list of image details from the Chicago Art Institute into my React application. I need help understanding APIs, so a detailed answer would be appreciated. I have the code for the image list but can't figure out how to make it wo ...

What is the process for importing components from a Stencil library into a React application?

After successfully creating: a stencilJS component library named "my-lib" using the "npm init stencil" wizard and an Ionic React app using "ionic start myApp tabs" I am now trying to incorporate the default "my-component," aka MyComponent from my-lib. H ...

What is the best way to assign a value to an option element for ordering purposes?

My select element is being populated with fruits from a database, using the following code: <select name="fruitsOption" id="fruitsOptionId" ngModel #fruitRef="ngModel"> <option *ngFor="let fruit of fruits">{{fruit}}</option> </selec ...

Tips on dynamically translating resources using ngx-translate

Can anyone help me with ngx-translate? I'm struggling to figure out how to dynamically translate resources in HTML. Here's an example: "agreement.status.0": "New", "agreement.status.1": "Rejected", ...

Best practices for effectively managing interface design

My current interface looks like this: export interface Folder { name: string; id: number; date: Date; } However, in the actual scenario, the JSON response provides the date as a string type. How should I handle this data transfer between the back-en ...

It seems that every time you save data in Angular, the local storage array gets overwritten

While using Angular, I encountered an issue with saving to local storage. The code works fine for saving items initially, but on refreshing the page and trying to add more objects to the local storage array, it overwrites instead of appending. Can you help ...

Issue with assigning Type (Date|number)[][] to Array<,Array<,string|number>> in Angular with typescript and google charts

Currently, I am utilizing Angular 8 along with the Google Charts module. My latest endeavor involved creating a Google Calendar Chart to complement some existing Google charts within my project. However, upon passing the data in my component.html file, I ...

Converting JSON to TypeScript in an Angular project

Within my Angular project, I have an HTTP service that communicates with a web API to retrieve JSON data. However, there is a discrepancy in the naming convention between the key in the JSON response (e.g., "Property" in uppercase) and the corresponding pr ...

I'm looking for ways to incorporate TypeScript definition files (.d.ts) into my AngularJS application without using the reference path. Can anyone provide

I'm interested in leveraging .d.ts files for enhanced intellisense while coding in JavaScript with VScode. Take, for instance, a scenario where I have an Angular JS file called comments.js. Within comments.js, I aim to access the type definitions prov ...

What is the process for importing the Scale type definition from the Scale module?

Recently, I've been utilizing the Tonal package within a Vite/Vue/Typescript project. My current task involves importing the type known as Scale from the Scale module. You can find the type definition here: export interface Scale extends ScaleType { ...

Select one of 2 parameters and begin typing

I recently encountered a situation where I needed to define a type with an id field (string) and an oldId field (number), but I wanted these fields to be exclusive. For example: { id: "1234", name: "foo" } { oldId: 1234, name: "b ...

Issue regarding custom CSS implementation in Angular project

Being a French speaker, I apologize in advance for any mistakes I might make. I am also fairly new to Angular, so if you could provide detailed explanations in your responses, it would be greatly appreciated. Thank you. I am trying to import a custom CSS ...

An unexpected runtime error occurred: TypeError - Unable to use map function on events

When fetching data using graphQL and rendering it on the page, an error occurs: Unhandled Runtime Error TypeError: events.map is not a function I'm unsure if my useState declaration is correct. const [events, setEvents] = useState < any > ([]) ...

Troubleshooting error "is not assignable to type..." when simulating global fetch using TypeScript

I am encountering an issue with the "global.fetch" part and cannot seem to figure out why. Despite following the standard procedure, I am still facing this TS2322 error. I am seeking assistance to understand why this error is occurring. I am open to sugges ...