Creating a generic class in Typescript that can only accept two specific types is a powerful

When designing a generic class, I am faced with the requirement that a property type must be either a string or number to serve as an index.

If attempting something like the code snippet below, the following error will be triggered:

TS2536: Type 'T' cannot be used to index type '{}'.

export class GenericClass<T> {
    public selectionMap: {[id: T]: boolean} = {};

    public isSelected(id: T): boolean {
      return !!this.selectionMap[id];
    }

    public toggleSelected(id: T): void {
        if (this.isSelected(id)) {
            delete this.selectionMap[id];
        } else {
            this.selectionMap[id] = true;
        }
        this.onChange();
    }
}

In my scenario, I can confidently assert that T will always be of type number or string. However, I am unsure of the correct syntax to maintain type safety in this case.

Answer №1

Here are two options to try:

export class GenericClass<T = string | number> {}

or

export class GenericClass<T extends string, number> {}

Ensure that the types used when calling the class are in lowercase as string and number. For more details, refer to this informative blog post.

Answer №2

How come you opted for using generics in this scenario? It may be more straightforward to utilize the specific types you require, or create a custom type that aligns with your requirements:

type Identifier = number | string;
export class UniqueClass {
    public chooseMap: {[id: Identifier]: boolean} = {};

    public checkSelection(id: Identifier): boolean {
      return !!this.chooseMap[id];
    }

    public toggleSelection(id: Identifier): void {
        if (this.checkSelection(id)) {
            delete this.chooseMap[id];
        } else {
            this.chooseMap[id] = true;
        }
        this.modify();
    }
}

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

What factors should I consider when determining whether to include @types/* in the `dependencies` or `devDependencies` section?

Currently using TypeScript 2 in my project, I am looking to incorporate a JavaScript library along with its typings. While I know I can easily install the types using npm install @types/some-library, I am uncertain whether to use --save or --save-dev. The ...

What is the best way to utilize the Moment.js TypeScript definition file in a website that already has moment.min.js integrated?

Currently, I am in the process of transitioning a website to utilize TypeScript by converting one JavaScript file at a time. All pages on my site are already linked to moment.js, such as: <script src="/scripts/moment.min.js"></script> I have ...

Implementing a variable for an array in Angular 4: A step-by-step guide

I need help determining the correct value for skill.team[variable here].name in Angular, where all team names are retrieved from the skill. Below is the code snippet: HTML <select [(ngModel)]="skill.teams[1].name" name="teamName" id="teamName" class= ...

Best practices for managing backend errors with Next.js 14

Currently, I am developing a project in Next.js 14 and I have set up my API requests using fetch within a handler.tsx file as shown below: async function getPositions() { const response = await fetch( process.env.BASE_API_URL + "/positions?enabl ...

Angular2- Techniques for exchanging data between isolated components

I am currently working on a project using Angular 2. Within this project, I have created two components: WorkspacesComponent and PagesComponent. In the database, each workspace contains a number of pages. I have written the code below to display the list ...

Only the (click) event is functional in Angular, while the (blur), (focus), and (focusout) events are not functioning

I have a unique HTML element as shown below <div (hover)="onHover()" (double-click)="onDoubleClick()" (resize)="resize()" (dragend)="dragEnd()"> These 4 functions are designed to display information onHover ...

Error in Typescript index: iterating over properties of a typed object

My scenario involves an interface that extends multiple other interfaces from an external library: interface LabeledProps extends TextProps, ComponentProps { id: string; count: number; ... } In a different section of the codebase, there is an ...

Observable<void> fails to trigger the subscriber

I am currently facing a challenge with implementing a unit test for an Observable in order to signal the completion of a process. While there is no asynchronous code in the logout function yet, I plan to include it once the full logic is implemented. The m ...

Error Raised Due to Modification After Checking in Angular 2/Angular 5

Dealing with ExpressionChangedAfterItHasBeenCheckedError in Angular 2/Angular5 Error message: An error has occurred: ExpressionChangedAfterItHasBeenCheckedError. The expression has changed after it was checked. Previously it was 'ng-untouched: ...

Leveraging ngModel within Form Arrays in Angular 4 with ReactiveFormsModule

While working with simple array forms in Angular 4, I encountered an unusual problem with ngModel ...

The mat-select component in Angular Material is failing to update/refresh when a new value is

Attempting to design an Angular Form for editing a record. When the user navigates to this edit form from the records list page, I aim to populate the fetched record from the API into the form elements while it loads. Utilizing the patchValue method within ...

Vue3 can accept a prop of type String or PropType

In my Vue3 project, I have a component that accepts a prop which can be either a string or an object. Here's how it looks: import { defineComponent } from 'vue' const Component = defineComponent({ props: { book: { type: [String, ...

List the hours using TypeScript

My data table is displaying records including a column for hours spent and a row showing the total sum of those hours. While the hours are being added correctly, the minutes display as NaN, such as 52:Nan. Can someone assist me in resolving this issue? co ...

Detecting Changes in the Backend with Angular

I'm curious about the best way to notify the frontend when there is a change in the backend. How can this situation be effectively handled? While developing an application on Azure, I have considered two possibilities, but none of them seem ideal. The ...

Angular deep linking in an Express server is a powerful combination that allows

I'm developing a single page application using Express and Angular. One feature involves sending users an email with a link to reset their password (https://[domain].com/reset-password/[token]). However, when the user clicks on this link, it redirect ...

Retrieve the previous route in Angular 7

I have developed a unique service that allows me to store route changes efficiently. import { Injectable } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; @Injectable() export class RouteState { priva ...

Error management and callback handling in MSAL.js for Angular 6 Single Page Applications

I am currently using msal.js in an angular 6 SPA for authentication purposes, but I have encountered a few issues: Initially, I struggled to find clear examples on how to handle errors with the library, so I pieced together information from various source ...

Tips for testing an Angular service method that returns a JSON object

I have a service in Angular that processes JSON input and returns JSON output after some operations. My positive test case for this service is failing consistently. I suspect the reason for this failure might be: Expected Result : [ Object({ key: &apos ...

The code encountered an error with message TS2345 stating that the argument type '(a: Test, b: Test) => boolean | 1' cannot be assigned to a parameter type of '(a: Test, b: Test) => number'

Apologies for the lengthy subject, but I am having trouble understanding the response. Here is my code snippet: this.rezerwacjeFilteredByseaarchInput.sort(function (a, b) { if (a[5]===null) { // console.log(a[5]); return 1; } ...

Encountered an Angular 2 error: NullInjectorError - Http provider not found

I've encountered an issue while trying to access a JSON GitHub service, receiving the error message NullInjectorError: No provider for Http! Although I've attempted to add providers throughout the code, my efforts have been unsuccessful. I' ...