A method for handling specific subsets of an enum in a secure and controlled manner

I have an enumerated type called Country and another type that represents a subset of European countries. I want to handle values within this subset differently from others. Currently, I am using an if statement with multiple conditions, but it could get unwieldy as the number of values in the subset grows.

enum Country {
    Canada,
    Finland,
    France,
    Germany,
    Japan,
    Peru,
}

type EuropeanCountries = Country.Finland | Country.France | Country.Germany;

const NonEuropeanCountriesContinent: Record<
    Exclude<Country, EuropeanCountries>,
    string
> = {
    [Country.Canada]: "America",
    [Country.Japan]: "Asia",
    [Country.Peru]: "America",
}

function getContinent(country: Country) {
    // Instead of manually checking each value, is there a better way to determine if the country is in the subset?
    if (country === Country.France || country === Country.Finland || country === Country.Germany) {
        return "Europe";
    }

    return NonEuropeanCountriesContinent[country];
}

How can I efficiently verify whether the value of my country variable is among the specified European countries without having to individually inspect each one?

Playground link

Answer №1

If you want to keep track of which enum values are part of the EU and which are not, you can create a Custom Type Guard to verify the type in the following way:

enum Country {
    Spain,
    Italy,
    Greece,
    Netherlands,
    China,
    Brazil,
}

type EuropeanCountries = Country.Spain | Country.Italy | Country.Netherlands;
const EuropeContinent: Record<EuropeanCountries, string> = {
    [Country.Spain]: "Europe",
    [Country.Italy]: "Europe",
    [Country.Netherlands]: "Europe",
}
const NonEuropeanCountriesContinent: Record<
    Exclude<Country, EuropeanCountries>,
    string
> = {
    [Country.Greece]: "Europe",
    [Country.China]: "Asia",
    [Country.Brazil]: "America",
}

function getContinent(country: Country) {
    if(isInEurope(country)) {
        return EuropeContinent[country];
    }

    return NonEuropeanCountriesContinent[country];
}

function isInEurope(country: EuropeanCountries | Exclude<Country, EuropeanCountries>): country is EuropeanCountries {
    return !!EuropeContinent[country as EuropeanCountries];
}

console.log(getContinent(Country.Spain));
console.log(getContinent(Country.China));

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

"encountered net::ERR_NAME_NOT_RESOLVED error when trying to upload image to s3 storage

I am currently developing an application using Angular. I have been attempting to upload a picture to my S3 bucket, but each time I try, I encounter this error in the console. https://i.stack.imgur.com/qn3AD.png Below is the code snippet from my upload.s ...

Unable to utilize class identifiers in TypeScript because of 'incompatible call signatures' restriction

Following the execution of relevant yarn add commands, the following lines were added to the packages.json: "@types/classnames": "^2.2.7", "classnames": "^2.2.6", Subsequently, I incorporated these lines into my typescript files: import * as classnames ...

Executing a function in the constructor of an Angular4 component

I am currently facing an issue where I am attempting to invoke a modal function within the constructor in Angular 4. However, it seems that the function is not being called properly as it gets highlighted. Upon loading the page, no errors are logged and th ...

What is the best way to extract multiple records from an Array?

Below is a simple filter function that filters Rec_pagedItems in an array called allItems. someval(value){ if(value.length>=5){ this._pagedItems= this.allItems.find(e=>e.uniqueid == value || e.name == value ); if(this._pagedItem ...

Extract Subscription Information from the .subscribe function in Angular

After calling the subscriber, I aim to fetch the events. This code successfully achieves this: getCalendarData(){ var body = JSON.stringify({"cid": "etNG3V61LWS6Pzkeb_omuZGMVAOLd1_70tRQblVizWQ~", "seldt":"2018-09-18"}); var headers = n ...

Localization of labels and buttons in Angular Owl Date Time Picker is not supported

When using the Owl Date Time Picker, I noticed that the From and To labels, as well as the Set and Cancel buttons are not being localized. Here is the code snippet I am using to specify the locale: constructor( private dateTimeAdapter: DateTimeAdapter&l ...

Troubleshooting TypeScript issues in an Angular 4 tutorial demo

I recently started working on the Angular tutorial provided on the official website. However, I have encountered an issue that I am struggling to resolve. After using Angular CLI to create the project, I came across the following code in app.component.ts: ...

To dismiss a popup on a map, simply click on any area outside the map

Whenever I interact with a map similar to Google Maps by clicking on various points, a dynamically generated popup appears. However, I am facing an issue where I want to close this popup when clicking outside the map area. Currently, the code I have writte ...

Assigning styles and values to an object using ngStyle

Within my component, I am encountering an issue where I am trying to edit some styles on a different component. I am passing an object to the component through property binding. The problem arises when updating the BorderRadius - it works when declaring a ...

Challenges with importing and using jspdf and autotable-jspdf in Angular 8

Issue with Generating PDF Using Angular 8, JSPDF, and JSPDF-AutoTable I am facing a challenge with exporting/generating a PDF based on an HTML grid. I need to make some DOM changes with CSS, remove toggle buttons, alter the header, etc. However, all the s ...

Having trouble consuming data from a service in Angular 6?

I'm in the process of creating a basic cache service in Angular; a service that includes a simple setter/getter function for different components to access data from. Unfortunately, when attempting to subscribe to this service to retrieve the data, t ...

Transmitting a base64 data URL through the Next.js API route has proven to be a challenge, but fortunately, other forms of

It's frustrating me to no end. I've successfully done this before without any problems, but now it just won't cooperate. Everything works fine when passing an empty array, a string, or a number. However, as soon as I include the data URL, t ...

Using a Typescript variable prior to its assignment

I encountered an issue in my Typescript / ReactJS project displaying the error message Variable 'myVar' is used before being assigned. TS2454 This problem arises with my TS version 4.2.3, appearing both in my IDE and during code execution. Inte ...

Mastering typing properties in React with TypeScript

Could someone please help me with this issue? I have created a basic react component. interface iRowData{ name: string } export default function ResultsSection(data: iRowData[]) { return <div>Results</div> } When I try to use it in ano ...

Is it possible to develop a C equivalent of the typescript Record type?

Is there a way to create a record type equivalent in C like what can be done in TypeScript, and add attributes during runtime? I am aiming to replicate the following: const familyData: string[] = ["paul", "em", "matthias", "kevin"]; const myFamily: Record ...

Issue encountered: `property does not exist on type` despite its existence in reality

Encountering an issue in the build process on Vercel with product being passed into CartItem.tsx, despite being declared in types.tsx. The error message reads: Type error: Property 'imageUrl' does not exist on type 'Product'. 43 | ...

Mapped TypeScript type requiring scalar properties and allowing optional objects

I am in need of a TypeScript generic type that has the capability to alter another type so that all scalar properties (such as strings, numbers, booleans, etc.) remain mandatory, while object types become optional. For instance, given the User type below, ...

The error message "The type 'MouseEvent' is non-generic in TypeScript" popped up on the screen

Having created a custom button component, I encountered an issue when trying to handle the onClick event from outside the component. I specified the parameter type for the onClickCallback as MouseEvent<HTMLButtonElement, MouseEvent>, which is typical ...

The issue of TypeError arising while invoking a method within TypeScript Class Inheritance

Currently, I am developing a Node.js application with TypeScript. In this project, I have a base controller class named BaseController and a derived controller called SettingController. The intention is for the SettingController to utilize methods from the ...

Top choice for React with TypeScript CodeMirror integration

Seeking recommendations for a package that seamlessly integrates with typescript in an existing react application. Specifically, looking to implement codeMirror functionality. Any suggestions? ...