What is the best way to filter by enum value in Typescript?

If I define an enum as follows:

export enum Status {
    InProgress = 0,
    Completed = 1,
    Cancelled = 2
}

and have a class that references the enum:

import { Status } from "./Status";
export class TaskDto {
  public name: string = null;
  public currentStatus: Status = null;
}
export default TaskDto;

I am encountering an issue where filtering based on the currentStatus property of TaskDto is not yielding any results.

//...some code to fetch data
let activeTasks = response.data.activeTasks as TaskDto[]; //correctly casts to an array of 4 items
let filteredTasks = activeTasks.filter(
  t => t.currentStatus === Status.Completed
);
//filteredTasks is empty when it should contain all 4 items

To workaround this issue, I converted the enum value to a string for comparison, although I feel this should not be necessary in TypeScript.

let filtered = filteredTasks.filter(
  t =>
    t.currentStatus.toString() === Status[Status.Completed]
);

Answer №1

It appears that the issue stemmed from how the server was transmitting the data back. The value of currentState for each GroceryDto was being sent as a string. Making the necessary adjustments to the enum definition, as suggested by @Aleksey, resolved the issue:

export enum Status {            
        Inactive = "Inactive",
        Active = "Active",
        Pending = "Pending"
    }

Answer №2

It's important to note that enum usage in TypeScript can be a bit tricky, as they are often misunderstood and can be used either as string-based or numeric-based types.

If you utilize your enum like this:

State.OnShoppingListUnchecked

It will be treated as a number and compared to the numeric value of 1. However, consider the following nested enum code:

a === State['OnShoppingListUnchecked'] // compare to 1
a === State[State['OnShoppingListUnchecked']] // compare to 'OnShoppingListUnchecked' string
a === State[State[State['OnShoppingListUnchecked']]] // Once again against numeric 1
// ... and so on 

If you are receiving a string from the server instead of a number, your comparisons may fail. You can automate this check by doing the following:

let toCompare = 1 // Value to compare against
if (typeof(compareValue) === 'number') {
  return State[toCompare] === compareValue // Compare number to number
} else if (typeof(compareValue) === 'string') {
  return State[State[toCompare]] === compareValue // Compare input string to string representation of enum
}

This ensures that regardless of whether the input is a string or number, you are comparing it against the correct enum entry.

String-based enums have been supported since TypeScript 2.4 and above, but in my opinion, their usage should be limited. Number-based enums provide an easy way to access additional information from array-like structures, which is not possible with string-based enums:

enum NamesEnum {
    NAME0 = 0,
    NAME1 = 1
};

namesToDisplay: string[] = [
  'Name1 display value',
  'Name2 display value'
];

let enumVal = someFunctionThatGetsEnum(); // Only works for number-based enums
this.currentDisplay = this.namesToDisplay[enumVal];

In the template:

<p>{{ currentDisplay }} </p>

If you don't need to index arrays using enums, you can replace string-based enums with String Literal Types, which offer similar benefits without as much concern for type and compatibility issues.

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

Is it possible for me to exclude generic parameters when they can be inferred from another source?

Imagine having a scenario like this: type RecordsObject<T, K extends keyof T> = { primaryKey: K; data: Array<T>; } where the type K is always derived from the type T. Oftentimes, when I try to declare something as of type RecordsObject, ...

Exploring dependency injection in Angular 1 using a blend of JavaScript and TypeScript

I'm currently working on integrating TypeScript into an existing Angular 1.5 application. Despite successfully using Angular services and third-party services, I am facing difficulties in injecting custom services that are written in vanilla JavaScrip ...

How to retrieve static attributes while declaring an interface

class A { public static readonly TYPE = "A"; } interface forA { for: A.TYPE } I am facing an issue while trying to access A.TYPE from the forA interface in order to perform type guarding. The error I encounter is: TS2702: 'A' only refe ...

Angular Update Component on Input ChangeEnsuring that the component is automatically

<div class=" card-body"> <div class="row"> <div class=" font-icon-list col-lg-2 col-md-3 col-sm-4 col-xs-6 col-xs-6" routerLinkActive="active" *ngFor="let subject of subjects"> <div class=" fon ...

Could this type declaration in the Vue decorator constructor be accurate?

When using Vue decorator notation, I typically write it like this: @Prop({ type: Object || null, default: null }) However, I noticed in the Vue documentation that they use array notation: @Prop({ type: [ Object, null ], default: null }) Is there a specif ...

Arranging an array of objects in typescript with elements implicitly having an undefined type

Currently, I am facing a challenge where I need to sort an array of objects within a function. The catch is that the function receives the key as a parameter, making it unknown: export interface ProductsList { id: boolean nome: string qtde: number ...

Issue with the scoring algorithm using Angular and Spring Boot

Hello, I have created a scoring algorithm to calculate scores, but I encountered an error in "salaireNet". ERROR TypeError: Cannot read properties of null (reading 'salaireNet') at ScoringComponent.calculateScore (scoring.component.ts:33:55) ...

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 ...

Storing an array of objects in local storage is not working in Angular 9

I've encountered an issue trying to save an array of JSON objects into local storage, and I'm puzzled as to why it's not functioning correctly. Despite utilizing localStorage.setItem('comparisons', JSON.stringify(setComparisons)), ...

Displaying Well-Formatted XML in Angular2 Using Typescript

After receiving this XML string from the server: <find-item-command xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" find-method="Criteria" item-class="com" only-id="false" xsi:schemaLocation=""> <criteria> <criterion> <descripto ...

The wildcard syntax for importing statements in Angular 2

I created multiple classes in a single file with the following structure file: myclasses.ts export class Class1 {....} export class Class2 {....} export class Class3 {....} Now I am attempting to import all of them using a wildcard like this import {*} ...

Unable to locate the module styled-components/native in React Native

When adding types in tsconfig.json to remove TypeScript complaints and enable navigation to a package, the code looks like this: import styled, {ThemeProvider} from 'styled-components/native'; The package needed is: @types/styled-components-re ...

Obtain data attributes using JQuery's click event handler

I'm facing an issue with a div structure setup as follows: <div class='bar'> <div class='contents'> <div class='element' data-big='join'>JOIN ME</div> <div class=& ...

Why is webpack attempting to package up my testing files?

In my project, I have two main directories: "src" and "specs". The webpack configuration entrypoint is set to a file within the src directory. Additionally, the context of the webpack config is also set to the src directory. There is a postinstall hook in ...

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 ...

Automatic completion of absolute paths in VS Code with the ability to click and view definitions through the configuration file js/tsconfig.json

In order to ensure that absolute paths function correctly, I have found that there are two key steps involved: the compilation process and configuring the code editor. I successfully managed the compilation aspect by utilizing babel-plugin-module-resolver ...

Angular2 bootstrapping of multiple components

My query pertains to the following issue raised on Stack Overflow: Error when bootstrapping multiple angular2 modules In my index.html, I have included the code snippet below: <app-header>Loading header...</app-header> <app-root>L ...

Retrieving the attribute key from a dynamically typed object

Having this specific interface structure: interface test { [key: string]: string } along with an object defined as follows: const obj: test ={ name: 'mda', telephone: '1234' } Attempting to utilize this object in a variab ...

A function in Typescript designed to take in two objects that possess identical keys

I am looking to define a function that takes two parameters, each being an object. These objects have the same keys, but the data types of the values under those keys should be different (yet the same within each object). I attempted to achieve this using ...

Unused code splitting chunk in React production build would improve performance and efficiency of

When running the command npm run build, a build directory is generated with js chunks. I have observed an unfamiliar file named [number].[hash].chunk.js that does not appear in the list of entrypoints in the asset-manifest.json file. Instead, this mysteri ...