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

An email value being recognized as NULL

create-employee.html <div class="form-group"> <label for="exampleInputEmail1">Email address</label> <span><input type="text" [required]="!standingQueue" class="form-control" name="exampleInputEmail1" ...

Creating a setup with Angular 2+ coupled with Webpack and a Nodejs

I have successfully configured Angular2+webpack along with NodeJs for the backend. Here is a basic setup overview: webpack.config.js: var webpack = require('webpack') var HtmlWebpackPlugin = require('html-webpack-plugin') var Extract ...

The error message "ReferenceError: window is not defined in Angular Universal" indicates

Currently, I'm utilizing Angular 10 and undergoing the process of incorporating SSR into my project. Upon executing the npm run serve:ssr, I encounter the following error: ReferenceError: window is not defined After conducting a search online, the r ...

Utilizing GroupBy in RxJs for an Observable of Objects数组

I am working with entries of type Observable<Event[]>, and they are structured as follows: [{ "_id": 1, "_title": "Test Event 1", "_startDate": "2019-05-29T07:20:00.000Z", "_endDate": "2019-05-29T08:00:00.000Z", "_isAllDay": false }, ...

Dynamic form groups in Angular: Avoiding the issue of form inputs not binding to form groups

Purpose My goal is to develop a dynamic form in Angular that adjusts its fields based on an array received from the backend. For example, if the array contains ["one", "two", "three", "four"], the form should only ...

What is the process for incorporating the jsnetworkx library into an ionic or angular 4 project?

When using any Ionic3 app service import * as jsnx from 'jsnetworkx'; The output error message is: Uncaught (in promise): Error: Cannot find module "lodash/lang/isPlainObject" Error: Cannot find module "lodash/lang/isPlainObject" at webpackMis ...

Encountering unanticipated breakpoints in compiled .Next files while using Visual Studio Code

As a newcomer to NextJS, I have encountered an issue that is disrupting my workflow. I followed the instructions in https://nextjs.org/docs/advanced-features/debugging#using-the-debugger-in-visual-studio-code to set up my launch.json file. Although I am ...

Learn how to dynamically import external modules or plugins using the import() functionality of TypeScript 2.4 within the production script generated by Angular CLI

Utilizing the typescript 2.4 [import()][1] feature has proven to be effective for dynamically loading modules. Testing this functionality has shown positive results, especially when importing modules and components located within the same directory. Howev ...

Leveraging an external TypeScript library in a TypeScript internal module

Imagine you find yourself in a situation where you need to utilize a typescript/node library within an internal module that is spanned across multiple .ts files. ApiRepositoryHelper.ts import * as requestPromise from "request-promise"; module ApiHelp ...

Typescript: Transforming generic types into concrete types

I am utilizing a Generic type type GenericType = { [key: string]: { prop1: string, prop2?: string, prop3?: number, }, }; The purpose of the Generic type is to assist in constructing / validating a new object that I have created. const NewO ...

Angular 9: The instantiation of cyclic dependencies is not allowed

After transitioning from Angular 8 to Angular 9, I encountered an issue with a previously functioning HTTP communication service. The error message now reads: Error: Cannot instantiate cyclic dependency! HttpService at throwCyclicDependencyError (core ...

Execute multiple observables concurrently, without any delay, for every element within a given list

I've been attempting to utilize mergeMap in order to solve this particular issue, but I'm uncertain if my approach is correct. Within my code, there exists a method named getNumbers(), which makes an HTTP request and returns a list of numbers (O ...

What is the best way to allocate string types from an enum using Typescript?

Within my code, I have an enum that includes a collection of strings export enum apiErrors { INVALID_SHAPE = "INVALID_SHAPE", NOT_FOUND = "NOT_FOUND", EXISTS = "EXISTS", INVALID_AUTH = "INVALID_AUTH", INTERNAL_SERVER_ERROR = "INTERNAL_ ...

What steps can be taken to effectively build a test suite architecture using Jest?

After exploring all the available resources on the Jest documentation website, including various guides and examples, I have yet to find a solution to my specific question. I am in search of a methodology that would enable me to individually run test case ...

Guide on validating multiple preselected checkboxes using Angular 8 reactive forms

I have a problem with validating checkboxes in my Angular application. The checkboxes are generated dynamically from an array using ngFor loop, and I want to make sure that at least one checkbox is selected before the form can be submitted. The validatio ...

I am retrieving data from a service and passing it to a component using Angular and receiving '[object Object]'

Searching for assistance with the problem below regarding my model class. I've attempted various approaches using the .pipe.map() and importing {map} from rxjs/operators, but still encountering the error message [object Object] export class AppProfile ...

Different categories of "areas" found in TypeScript within Visual Studio 2013

In C#, we often use "regions," but unfortunately that feature is missing in TypeScript. Is there a way to group code sections in TypeScript? I came across this article on Stack Overflow discussing the absence of regions in TypeScript. I'm curious if ...

Angular - delay execution until the variable has a value

When the ngOnInit() function is called, the first line of code retrieves a value from local storage which is then used to filter data from the database. Both actions happen simultaneously, resulting in an issue where I don't receive the expected resu ...

Collection of functions featuring specific data types

I'm currently exploring the idea of composing functions in a way that allows me to specify names, input types, and return types, and then access them from a central function. However, I've encountered an issue where I lose typing information when ...

Erase Typescript Service

To remove a PostOffice from the array based on its ID, you can use a checkbox to select the desired element and then utilize its ID for the delete function. Here is an example: let postOffices = [ {postOfficeID: 15, postCode: '3006&ap ...