Is it possible to have different property types within the same TypeScript class?

I'm currently working with TypeScript and Angular.

I have two services that are quite similar, but they have different properties:

  synchronizedMaps: Map<string, Map<string, MapSynchSettings>> = new Map<string, Map<string, MapSynchSettings>>();
  groupDispatchers: Map<string, Subject<SynchMapGroupSubject>> = new Map<string, Subject<SynchMapGroupSubject>> ();
  mapDispatchers: Map<string, Subject<SynchMapSubject>> = new Map<string, Subject<SynchMapSubject>> ();

  public createNewSynchGroup(id?: string): Observable<SynchMapGroupSubject> {

    this.synchronizedMaps.set(id, new Map<string, MapSynchSettings>());
    this.groupDispatchers.set(id, new Subject<SynchMapGroupSubject>());
    this.mapDispatchers.set(id, new Subject<SynchMapSubject>());

    return this.groupDispatchers.get(id).asObservable();
}

and

  synchronizedDrawer: Map<string, Map<string, SynchWaypointDrawerSettings>> = new Map<string, Map<string, SynchWaypointDrawerSettings>>();
  groupDispatchers: Map<string, Subject<SynchWaypointDrawerGroupSubject>> = new Map<string, Subject<SynchWaypointDrawerGroupSubject>> ();
  waypointDispatchers: Map<string, Subject<SynchWaypointSubject>> = new Map<string, Subject<SynchWaypointSubject>> ();

  constructor() { }

  public createNewSynchGroup(id?: string): Observable<SynchWaypointDrawerGroupSubject> {
    this.synchronizedDrawer.set(id, new Map<string, SynchWaypointDrawerSettings>());
    this.groupDispatchers.set(id, new Subject<SynchWaypointDrawerGroupSubject>());
    this.waypointDispatchers.set(id, new Subject<SynchWaypointSubject>());

    return this.groupDispatchers.get(id).asObservable();
}

Although the property types and returned method values differ, the logic and implementation of these two services are identical.

I am exploring ways to potentially merge these two services into one or create a parent class that I can extend with only variable type changes while keeping all the logic and naming conventions consistent.

Thank you.

Answer №1

If you're looking for a solution, one approach is to utilize a generic class. In this method, you can employ type parameters to specify the types later on:

class GeneralItem<A, B, C> {
    holder: Map<string, Map<string, A>> = new Map();
    groupers: Map<string, Subject<B>> = new Map();
    dispatchers: Map<string, Subject<C>> = new Map();

    public createNewItemGroup(identifier?: string): Observable<B> {
        if (!identifier) throw new Error("Oops!");

        this.holder.set(identifier, new Map());
        this.groupers.set(identifier, new Subject<B>());
        this.dispatchers.set(identifier, new Subject<C>());

        return this.groupers.get(identifier)!.asObservable();
    }
}

In the provided code snippet, I've renamed the properties as more generic terms (holder and dispatchers) and specified the type parameters as A, B, and C.

You can then define the services as

GeneralItem<MapSettings, GroupSubject, ItemSubject>

or

GeneralItem<DrawerSettings, DrawerGroupSubject, DrawerSubject>

Alternatively, you could assign them distinct names like

class Maps extends GeneralItem<
  MapSettings, 
  GroupSubject, 
  ItemSubject
> {}

class Drawers extends GeneralItem<
  DrawerSettings, 
  DrawerGroupSubject, 
  DrawerSubject
> {}

I hope this explanation aids you in your endeavors. Best of luck!

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

Ensure that a particular key type is determined by the value of another key within the object (Utilizing Discriminated Unions)

The title of my question may not have been clear about what I am looking for, but what I need is something known as discriminated unions. You can find more information about it here: https://www.typescriptlang.org/docs/handbook/unions-and-intersections.htm ...

Adjusting the timeout for a particular operation according to its unique identifier

I am looking for a solution to call a method that posts an answer after an input change in my Angular project. I want to reset the timeout if another input change occurs to avoid multiple posts. Is there a smart way to achieve this? My project involves po ...

Sharing a Promise between Two Service Calls within Angular

Currently, I am making a service call to the backend to save an object and expecting a number to be returned via a promise. Here is how the call looks: saveTcTemplate(item: ITermsConditionsTemplate): ng.IPromise<number> { item.modifiedDa ...

Positioning the search bar to the left with react-bootstrap-table

Is there a way to move the search bar of react-bootstrap-table to the left instead of keeping it on the right? You can see an example here, at the bottom of the page: I know that you can create a custom search panel and input, but that seems like a compl ...

How can I incorporate loading animations within a for loop in Angular 17?

I am currently working on a Video Gallery website showcasing my YouTube videos, all embedded using the iframe tag. However, I have been facing slow load times when opening the page. I want to incorporate some form of loading animation or method to improve ...

Issue encountered while attempting to enclose a function within another function in Typescript

I'm attempting to wrap a function within another function before passing it to a library for later execution. However, I'm encountering various Typescript errors while trying to utilize .apply() and spread arguments. The library mandates that I ...

Tips for properly executing directives in sequential order while using async in Angular 13

I created a standard registration form using Angular and implemented an async directive (UserExistsDirective) to validate if the email is already taken. To manage error messages, I also utilized a second directive (ValidityStyleDirective) which is also use ...

Collaborating on a project that has been developed using various editions of Typescript

Currently, I am part of a team working on a large project using Typescript in Visual Studio. As we have progressed through different versions of the project, we have encountered an issue with versioning the installed TypeScript within Visual Studio. Situa ...

Ensure the initial word (or potentially all words) of a statement is in uppercase in Angular 2+

Struggling with capitalizing words in an Angular 2 template (referred to as view) led to an error in the console and the application failing to load, displaying a blank page: Error: Uncaught (in promise): Error: Template parse errors: The pipe 'c ...

Misunderstanding between Typescript and ElasticSearch Node Client

Working with: NodeJS v16.16.0 "@elastic/elasticsearch": "8.7.0", I am tasked with creating a function that can handle various bulk operations in NodeJS using Elasticsearch. The main objective is to ensure that the input for this funct ...

Is there a way to retrieve the Windows username without manual input?

Currently, I am working on creating an internal web portal for our organization. The technologies I am using include Angular 5, Java Spring, REST, JDBC, JSON, and MS SQL Server. To ensure seamless authentication on my website, I have implemented a method ...

Can you pass a generic type as a parameter for another generic in Java?

Simply provide a generic type like a callback: type FUNC<ARG,RET, F> = (arg: ARG) => F<RET>; type PROMISE<T> = Promise<T>; type IDENT<T> = T; type A = FUNC<number, void, IDENT>; type A_PROMISE = FUNC<number, void, ...

Guide for Serving JSON in Next.js when not-found.tsx is Accessed

I've recently been tackling a project with Next.js 14 and have successfully configured a customized 404 page by utilizing the not-found.tsx file located in the root of the application. However, I'm facing a challenge when it comes to returning a ...

Having an issue with my Typescript code that is throwing a "Uncaught ReferenceError: angular is not defined" error

I am currently in the early stages of learning typescript with angularjs through online video tutorials. I have encountered an issue while attempting to include the angular module in my "app.ts" file, which serves as the main file in the backend. Below is ...

Express application (utilizing TypeScript) failing to handle routes efficiently

Encountering a technical issue : I am developing a REST API, but my application does not seem to trigger the actions when I send a request to the endpoint. This is my server configuration: import express, { Express } from 'express'; import c ...

Resolving the Error: "Type 'Customer | undefined' is not compatible with type 'Customer'" in Angular

I encountered an issue with the following code: ... export class ListCustomersComponent implements OnInit { customers: Array<Customer> = []; showCustomer?: Customer; isSelected: boolean = false; deletedCustomer?: Customer; returnedMessa ...

Rearranging items within an array in a React component

Currently, I am facing a situation where I have created a list that dynamically adds a React Node upon clicking a button. The final layout of the model looks like this: https://i.sstatic.net/fG37r.png Here is the code snippet for your reference: import ...

Transferring files from one azure blob container to another

I am currently utilizing the @azure/storage-blob package to manage files within Azure. Within the same Azure storage account, I have two storage containers - one for source files and the other for destination files. My objective is to copy a file from th ...

I am interested in incorporating a delete button within my Angular application

I am working on an Angular App and I need to implement a remove button for a div element. Currently, I have an add button function in my ts file: uploads = []; addUp() { this.uploads.push(this.uploads.length); } I attempted to create the remove b ...

Implementing an Ant Design Form field for an array of objects

Is it possible to edit an entity with a one-to-many relation? { id: 1, title: 'Title', tags: [ { id: 1 }, { id: 2 }, ], } Here is the code snippet: <Form.Item name={["tags", "id"]} > < ...