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

What methods are available to rapidly test Firebase functions?

While working with Typescript on firebase functions, I have encountered challenges in testing and experimenting with the code. Despite using the Lint plugin to identify errors without running the code, I am struggling to run the code and view the output. ...

An operator in rxjs that transforms an Observable of lists containing type X into an Observable of type X

Currently, I am facing a challenge while dealing with an API that is not very user-friendly using Angular HTTP and rxjs. My goal is to retrieve an Observable<List<Object>> from my service. Here's a snippet of the JSON output obtained from ...

The HTTP post method in Angular 2 fails to properly send data to request.JSON within a Grails Action

Having trouble retrieving data from request.JSON passed through an Angular 2 HTTP POST method. The Grails action is being triggered, but the request.JSON is consistently empty {} even when data is passed. ANGULAR2: HTTP POST Method: return this.http.pos ...

Growing the category beyond just an object

I'm dealing with some Python classes: class Window(object): def __init__(self, name): self.wind_name = name def getWindowName(self): return 'wnd' + self.wind_name class Control(object): def __init__(self, name, ...

Using type hints for a JSON object in Python

Is there a way to specify type hints for JSON objects with an unknown or changing structure? I want to avoid using Any or methods like cast() as much as possible. I think the correct hint would be: Json: TypeAlias = dict[str, "Json"] | list[&quo ...

Issue with MathJax rendering within an Angular5 Div that's being observed

I am trying to figure out how to enable MathJax to convert TeX to HTML for elements nested within my div. Here is the current content of app.component.html: <p> When \(a \ne\) It works baby </p> <div class="topnav"> ...

What is the reason behind TypeScript's lack of inference for function parameter types when they are passed to a typed function?

Check out the code snippets below: function functionA(x: string, y: number, z: SpecialType): void { } const functionWrapper: (x, y, z) => functionA(x, y, z); The parameters of functionWrapper are currently assigned the type any. Is there a way we can ...

Customizing the header template in ag-Grid for Angular 2

I have implemented ag-grid within an ng2 component. Now, I am trying to make the first header a checkbox with the parent functionality. How can I achieve this from the container component? ag-grid.component @Component({ moduleId: module.id, selecto ...

The npm build encountered an issue: An unexpected value of 'undefined' was declared by the module

I am encountering issues while attempting to construct my Angular 5 project that ultimately leads to failure. Here is an overview of the dependency tree: simple-kaishi <- kaishi <- ngx-admin-lte ngx-admin-lte: (develop branch) represents the ...

The compiler error TS2304 is indicating that it cannot locate the declaration for the term 'OnInit'

I successfully completed the Angular superhero tutorial and everything was functioning properly. However, when I close the CMD window running NPM and then reopen a new CMD window to reissue the NPM START command, I encounter two errors: src/app/DashBoard ...

Issue encountered when working with Next Auth and TypeScript: The argument type 'string | undefined' cannot be assigned to the parameter type 'string | Buffer'

Encountering a TypeScript error that states: "Argument of type 'string | undefined' is not assignable to parameter of type 'string | Buffer'." An attempt to integrate NextAuth into a Next.js 14 application and configure logi ...

Running an Angular application on dual hosts

Is it possible to host the same Angular application on multiple hosts, such as different IP addresses or ports, using Node.js? ...

Tips for accurately defining the return type for querySelector(All) connections

I enjoy doing this particular task, ensuring the types are correct. const qs = document.querySelector.bind(document) as HTMLElementTagNameMap | null; const qsa = document.querySelectorAll.bind(document) as NodeListOf<any>; While hovering over query ...

Tips on mocking an ngrx selector within a component

Within a component, we utilize an ngrx selector to access various segments of the state. public isListLoading$ = this.store.select(fromStore.getLoading); public users$ = this.store.select(fromStore.getUsers); The fromStore.method is formed using the ngrx ...

Error message encountered following the removal of an undesirable type from an array in Typescript

When working with TypeScript, I am facing an issue. I have an array defined as Array<string|undefined, and my goal is to filter out the undefined values from this array and assign the resulting array to a variable of type Array<string>. However, I ...

Securing Angular 2 routes with Firebase authentication using AuthGuard

Attempting to create an AuthGuard for Angular 2 routes with Firebase Auth integration. This is the implementation of the AuthGuard Service: import { Injectable } from '@angular/core'; import { CanActivate, Router, Activated ...

Execute the eslint loader within the node_modules of a specific directory that is npm linked and has not been compiled

One of the benefits of using webpack 4 is the ability to run eslint across the entire project folder with a specific configuration. { enforce: 'pre', test: /\.js|ts$/, exclude: /node_modules/, loader: 'eslin ...

Ensure that the variable is not 'undefined' and that it is a single, clean value

In my node backend project, I've encountered a situation with my TypeScript code where a variable occasionally prints as the string 'undefined' instead of just being undefined. Is there a more elegant way to check that the variable is not eq ...

Using TypeScript, effortlessly retrieve objects within React components based on their keys

I am looking for a way to dynamically choose a React component based on a key within an object import React, {useState, useEffect} from 'react' import ComponentA from '@components/ComponentA'; import ComponentB from '@components/Co ...

The query for PrManagerBundleEntityeb_user is missing the identifier id

In an attempt to delete an object by its ID from the database using the following code in the frontend, I encountered an issue where the link does not function as expected. Here is the error message that I received: The identifier id is missing for a quer ...