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

Using Jimp to load a font and retrieve its Base64 representation

I am currently working in Angular with Jimp, attempting to overlay text onto an existing image. However, the image is not updating as expected. const Jimp = require('jimp') var _this = this; Jimp.read("assets/TimeLine.png").then(function ( ...

The random number generator in TypeScript not functioning as expected

I have a simple question that I can't seem to find the answer to because I struggle with math. I have a formula for generating a random number. numRandomed: any; constructor(public navCtrl: NavController, public navParams: NavParams) { } p ...

Tips for styling the Button component in the shadcn/ui library for maximum impact

I'm currently working on a project using the shadcn/ui library. How can I properly customize it to meet my specific needs? For example, let's say I require an extra large red rounded Button for a call-to-action button in my project. What would be ...

The error message "Identifier 'title' is not defined. '{}' does not contain such a member angular 8" indicates that the title variable is not recognized or defined in the

Here is the code snippet of my component: import { Router, ActivatedRoute } from '@angular/router'; import { Component, OnInit } from '@angular/core'; import { CategoriesService } from 'src/app/categories.service'; import { P ...

The use of async/await within an observable function

I am looking to establish an observable that can send values to my observers. The issue lies in the fact that these values are acquired through a method that returns a promise. Is it possible to use await within the observable for the promise-returning f ...

What could be causing the issue of my application not being able to operate on the specified port on Heroku?

After spending two whole days trying to decipher the Heroku error message with no success, I'm still unable to pinpoint what is causing the issue. 2021-07-18T04:27:08.741998+00:00 app[web.1]: {"level":30,"time":1626582428741,&quo ...

Tips for utilizing generics to determine the data type of a property by its name

I am seeking a method to determine the type of any property within a class or a type. For instance, if I had the classes PersonClass and PersonType, and I wanted to retrieve the type of the nationalId property, I could achieve this using the following cod ...

Exploring the distinction between "() => void" and "() => {}" in programming

Exploring TS types, I defined the following: type type1 = () => {} type type2 = () => void Then, I created variables using these types: const customType1: type1 = () => { } const customType2: type2 = () => { } The issue surfaced as "Type ...

Having trouble setting up Nuxt with Typescript integration

I am venturing into the world of Typescript with Nuxt (version 2.6.1) for the first time. After creating a new project using create-nuxt-app, I followed the official guide for Typescript Support. npx create-nuxt-app my-first-app cd my-first-app npm instal ...

What steps can I take to make my animation work in the opposite direction as well?

I'm currently working with an angular slider that is set to TRUE/OPEN by default. The issue I am facing is that while I am able to slide it using angular animations in one direction, I am unable to see the transition when sliding it back. Any assistan ...

What is the best way to create a T-shaped hitbox for an umbrella?

I've recently dived into learning Phaser 3.60, but I've hit a roadblock. I'm struggling to set up the hitbox for my raindrop and umbrella interaction. What I'd love to achieve is having raindrops fall from the top down and when they tou ...

How can I pass DOCUMENT in Angular?

In my directive, I use dependency injection to access the DOCUMENT and set up an event listener: constructor(@Inject(DOCUMENT) private document: Document) {} ngOnInit() { this.document.addEventListener('click', this.clicked, true); } @Bound ...

Unable to retrieve data following a promise in Ionic 3

Hello, I'm currently working on an Ionic application that needs to display data in a Form Group after retrieving it with a SOAP ReadData request. Although I call my function and try to display the data in the form, there seems to be an issue as the f ...

What is the best way to preserve an enumeration value in TypeScript?

Is there a way to save enumeration values in TypeScript? For instance: createArticle(name: string, clr: ??enumeration??) { return axios.post(`${environment.apiUrl}/cards`, { card: `${name}`, color: ??clr?? }, ... } PS: Conte ...

Tips for utilizing ngIf based on the value of a variable

Here is the code from my file.html: <button ion-button item-right> <ion-icon name="md-add-circle" (click)="save();"></ion-icon> </button> The content of file.ts is: editmode = false; I am trying to achieve the foll ...

Tips for Simplifying Complex Switch Cases with Object Literals in TypeScript

I have a unique situation where I need to switch between two functions within an object literal. One function takes two numerical arguments, "A" and "B", while the other function only takes a single string argument, "C". My TypeScript code showcases my di ...

How can data be transferred between controllers in Angular 2 without using URL parameters or the $state.go() function?

I've encountered an issue where I need to pass a parameter from one controller to another without it being visible in the URL. I attempted to do so with the following code: this.router.navigate(['/collections/'+this.name], {id: this.id}); ...

Angular 6 component experiencing issues with animation functionality

I've implemented a Notification feature using a Notification component that displays notifications at the top of the screen. The goal is to make these notifications fade in and out smoothly. In my NotificationService, there's an array that holds ...

Is Highcharts-angular (Highcharts wrapper for Angular) compatible with Angular 4?

I have attempted to install various versions of highcharts-angular, ranging from 2.0.0 to 2.10.0. However, I consistently encounter the same error when running the application. The error message states: Metadata version mismatch for module C:/dev/Angular- ...

Problem encountered in a simple Jest unit test - Unexpected identifier: _Object$defineProperty from babel-runtime

Struggling with a basic initial test in enzyme and Jest during unit testing. The "renders without crashing" test is failing, as depicted here: https://i.stack.imgur.com/5LvSG.png Tried various solutions like: "exclude": "/node_modules/" in tsconfig "t ...