Inheritance in Angular with TypeScript Using Generic Types

Looking for some assistance from the angular2 / typescript experts out there to guide me in the right direction before I lose my mind :-)

Here's what I'm trying to achieve:

  • I want to create a parent class that implements its own defined parent Interface, using Generic Types so that when creating a child class, I can provide it with the specific and tailored class & data Interface.
  • The child class should be able to extend the parent data class by
    • Overriding default/parent set variables
    • Overwriting parent functions() and having the child's version called instead of the parent's default

In the sample pseudo code below, I expect the call to the child's (inherited) someOtherfunction() to return "2"...

Is this too much to ask for? I've been searching online but couldn't find any good examples...

Any guidance on how to accomplish this would be greatly appreciated!

Thank you, Oliver

(NOTE: THE CODE BELOW IS FOR DEMONSTRATION PURPOSES AND MIGHT NOT BE FUNCTIONAL)

// 
// Parent Class
// 

export interface ICoreData <T> {
    observeItems: Observable<T[]>;
    items: Array<T>;
}

@Injectable()
export class CoreData<T> implements ICoreData<T> {

    public observeItems: Observable<T[]>;
    private items: Array<T>;

    constructor( 'Dependency Injection...' ) {}

    coreFunction(): number {
        return 1;
    }
    someOtherfunction(){
        return this.coreFunction();
    }
}

// 
// Child class
// 

export interface IMyDataStructure {
    name: string;
    age: string;    
}

export interface ISpecificData extends ICoreData<IMyDataStructure> {
    someExtraKey: number;
}

@Injectable()
export class SpecificData extends CoreData<IMyDataStructure> implements ISpecificData {

    constructor() {
        super();
    }

    coreFunction(): number{
        // 
        // This function should "override" the parent's original function 
        // and be called by the parent's someOtherfunction() function 
        // 
        return 2;
    }
}

Answer №1

It's not too much to ask. However, using interfaces won't achieve what you're attempting to do. To accomplish your goal, you need to extend a class, which can be generic.

An interface serves as a contract or blueprint for a data type without any associated functionality. In your case, you wanted methods on the base class that could be overridden in the derived class.

The usual approach is to define an abstract base class (to prevent instantiation) and then create classes by extending it. Here's an example:

For simplicity, I've omitted Angular2 elements from the example.

abstract class Base<T> {
  constructor(public controlled: T) { }

  doIt(): string {
    return `Base.doIt: ${JSON.stringify(this.controlled)}`;
  }

  doSomethingElse(): string {
    return `Base.doSomethingElse: ${JSON.stringify(this.controlled)}`;
  }
};

interface Foo {
  foo: string;
  bar: string;
};

class Derived extends Base<Foo> {
  constructor(foo: Foo) {
    super(foo);
  }

  doSomethingElse(): string {
    return `Derived.doSomethingElse: ${JSON.stringify(this.controlled)}`;
  }
};

let d: Derived = new Derived({ foo: 'foo', bar: 'bar' });

console.log(`doIt ==> ${d.doIt()}`);
console.log(`doSomethingElse ==> ${d.doSomethingElse()}`);

Output:

doIt ==> Base.doIt: {"foo":"foo","bar":"bar"} 
doSomethingElse ==> Derived.doSomethingElse: {"foo":"foo","bar":"bar"}

Playground link.

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

Creating a JSX syntax for a simulated component and ensuring it is fully typed with TypeScript

Looking for some innovative ideas on how to approach this challenge. I have a test helper utils with added types: import { jest } from '@jest/globals' import React from 'react' // https://learn.reactnativeschool.com/courses/781007/lect ...

Combining the Partial<CssStyleDeclaration> union type with a dictionary can lead to potential typing complications when the implicit any flag is

Using VueJS v-bind:style binding makes it possible to set CSS variables. I am attempting to create a union type that allows for the object passed to v-bind:style to retain typings for CssStyleDeclaration, while also being relaxed enough to accept an arbitr ...

Create a TypeScript interface that represents an object type

I have a Data Structure, and I am looking to create an interface for it. This is how it looks: const TransitReport: { title: string; client: string; data: { overdueReviews: number; outstandingCovenantBreaches ...

What is the best way to retrieve TemplateRef from an Angular component?

TS Component ngOnInit() { if(somecondition) // The line of code that is causing issues this.openModal(#tempName); } HTML Component <ng-template #tempName> Content goes here! </ng-template> this.openModal(#tempNa ...

Swapping out a class or method throughout an entire TypeScript project

Currently, I am working on a software project built with TypeScript. This project relies on several third-party libraries that are imported through the package.json file. One such library includes a utility class, utilized by other classes within the same ...

Troubleshooting Issue with Angular 5: Inability to Hide Elements for Non-Authenticated Users

Below is the code from app.component.html <nav class='navbar navbar-default'> <div class='container-fluid'> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-targ ...

Animate exclusive fresh components

Exploring the functionalities of the latest animation API in Angular 2 has presented me with an interesting challenge: Within my parent component, I am utilizing *ngFor to display a series of child components. These child components are connected to a sim ...

Are there any restrictions on the amount of data that can be included in a Sankey diagram created from an Excel sheet? I would

[please provide a description of the image][1]I am encountering an issue with data limitation in plotting a Sankey diagram from an Excel sheet. I have imported an Excel sheet with 1300 rows of data, but I am only able to plot 12 rows of data. Can anyone pl ...

Refreshing/reloading Angular 9 SSR pages

Encountering an issue with Angular and SSR. Running angular 9, everything runs smoothly except when I refresh the page (F5), it first displays the login page before loading the current page. Previously built with angular 8, where this problem did not occur ...

Encountering difficulties redirecting to the homepage following Facebook login

After successfully logging in with Facebook, I am having trouble redirecting to my home page. The token is stored in localStorage, but it remains on the login page without redirecting. loginWithFB() { this.facebook.login(['public_profile', &a ...

The constant LOCALE_ID is always set to en-US and remains unchanged

app.module.ts import { registerLocaleData } from '@angular/common'; import localeIndia from '@angular/common/locales/en-IN'; import additionalLocaleIndia from '@angular/common/locales/extra/en-IN'; registerLocaleData(localeInd ...

Transmit a sequence of keys to the web browser

I'm having difficulty in sending a Shift key command followed immediately by tilde (~). I've attempted various examples, and here's one that I'm currently working on. I am testing the following scenario - selecting a specific image, t ...

Can errors be selectively ignored in Angular's global error handler based on certain conditions?

I am currently facing a situation where I need to handle errors when calling an API to save data, either manually or automatically. For manual saves, I have implemented an Angular global error handler to display the error message if the save fails. Howeve ...

How can I suggest the return type of a function that is out of my control?

When I attempt to parse a JSON-formatted string, a linter error is triggered: let mqttMessage = JSON.parse(message.toString()) // ESLint: Unsafe assignment of an `any` value. (@typescript-eslint/no-unsafe-assignment) Given that I am in control of the con ...

Utilizing functions from external modules in Angular

Recently, I created an es6 module with some exported functions and published it on npm after uploading its transpiled es5 code. Right now, I am in the process of trying to integrate this package into an Angular project that utilizes SystemJS as a module l ...

Step-by-step guide on integrating StyleX into your fresh React project

As I delve into my new project, incorporating StyleX has proven to be a bit challenging especially when working with NextJS. I find myself grappling with configuring the "next.config.js" file without causing conflicts with the existing "babel.config.js" f ...

Could it be possible for TypeScript inference to directly infer the value and omit the key in the process?

class A { state: B } class B { something: C } class C { a: string; b: boolean; } type MagicType = ... const c: MagicType<A> c.state.a = "123" c.state.b = true; Is it possible to achieve the mentioned functionality without altering the exi ...

Once the Angular project has been initialized, the Button disable attribute cannot be modified

In my Ionic-Angular project, I am creating registration pages where users input their information in multiple steps. For each step, there is a button that remains disabled until the correct information is entered. An issue arises when transitioning to the ...

Encountering a runtime issue with socket.io when using typescript that has been bundled by

Recently, I attempted to implement web sockets using socket.io in a Node server written in TypeScript with ExpressJS and bundled with Webpack. The server code is structured as follows: import * as Express from "express"; import * as SocketIO from "socket ...

Invalid file name detected during the download process

Below is the Javascript code I currently use to download a pdf: var link = document.createElement('a'); link.innerHTML = 'Download PDF file'; link.download = "Report.pdf"; link.href = 'data:application/octet-stream;base64 ...