"Implementing an abstract method in a class by overloading it with a generic type that

// Greetings from the TypeScript Playground, a platform where you can experiment with TypeScript code.
type Constructor<T> = new (...args: any[]) => T;

class ServiceChecklistResponse {
}
class AnotherModel {
}

abstract class AbstractView {
        getJsonDataModelRef<T>() : Constructor<T> | null
    {
        return null;
    }
    getAnotherDataModel<T>(): Constructor<T> | null
    {
        return null;
    }
}
class testView extends AbstractView {
    getJsonDataModelRef<ServiceChecklistResponse>() : Constructor<ServiceChecklistResponse> | null {
            return ServiceChecklistResponse;
    }
    getAnotherDataModel<AnotherModel>() : Constructor<AnotherModel> | null
    {
        return AnotherModel;
    }

}
Type 'typeof ServiceChecklistResponse' is not assignable to type 'Constructor<ServiceChecklistResponse>'.
  Type 'ServiceChecklistResponse' is not assignable to type 'ServiceChecklistResponse'. Two different types with this name exist, but they are unrelated.
    'ServiceChecklistResponse' could be instantiated with an arbitrary type which could be unrelated to 'ServiceChecklistResponse'.
Type 'typeof AnotherModel' is not assignable to type 'Constructor<AnotherModel>'.



  Type 'AnotherModel' is not assignable to type 'AnotherModel'. Two different types with this name exist, but they are unrelated.
    'AnotherModel' could be instantiated with an arbitrary type which could be unrelated to 'AnotherModel'.

Can someone please explain why this issue is happening and suggest how it can be resolved? It is necessary for it to return a class reference because a controller will utilize it later on.

const Model = myView.getJsonDataModelRef()
const foo = new Model()

Answer №1

When working with TypeScript, it's important to understand the distinction between generic types and generic functions, as they serve different purposes.


Generic types involve type parameters that are part of the type itself. In this case, you must provide a type argument when referring to the type:

type Foo<T> = (x: T) => T;
interface Bar<T> { y: T };
class Baz<T> { z: T; constructor(z: T) {this.z = z;} }

In this scenario, specifying the type parameter is crucial for instantiation and implementation flexibility.


In contrast, generic functions have the type parameter as part of the function signature. You only need to specify the type argument when calling the function:

function foo<T>(x: T) { return x; }
interface Bar { bar<T>(y: T): T; }
class Baz { baz<T>(z: T) { return z; } }

Here, the caller determines the type argument, adding versatility to the function.


Reviewing your code snippet reveals generic methods within a non-generic class. To ensure clarity and consistency, consider making the class itself generic:

abstract class AbstractView<J, D> {
  getJsonDataModelRef(): Constructor<J> | null {
    return null;
  }
  getAnotherDataModel(): Constructor<D> | null {
    return null
  }
}

This adjustment allows each subclass to define specific type arguments for the class instance, promoting better design practices.


By restructuring your code in this manner, you can achieve the intended behavior and maintain code integrity moving forward.

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

Tips on how to effectively simulate a custom asynchronous React hook that incorporates the useRef() function in jest and react-testing-library for retrieving result.current in a Typescript

I am looking for guidance on testing a custom hook that includes a reference and how to effectively mock the useRef() function. Can anyone provide insight on this? const useCustomHook = ( ref: () => React.RefObject<Iref> ): { initializedRef: ...

Ways to decrease the size of this item while maintaining its child components?

Here is an object that I am working with: { "name": "A", "children": [ { "name": "B", "open": false, "registry": true, "children": [ { ...

What is the best way to inform TypeScript when my Type has been altered or narrowed down?

In my application, I have a class that contains the API code: export class Api { ... static requestData = async ( abortController: React.MutableRefObject<AbortController | null> ) => { // If previous request exists, cancel it if ...

Utilizing Angular2 with Firebase for efficient denormalized data queries

I am currently working on crafting a query for a denormalized database. Drawing inspiration from the example showcased in Firebase's blog post, my objective is to: Retrieve the array of forms associated with the current user and return references to ...

Can you point me in the direction of the Monaco editor autocomplete feature?

While developing PromQL language support for monaco-editor, I discovered that the languages definitions can be found in this repository: https://github.com/microsoft/monaco-languages However, I am struggling to locate where the autocompletion definitions ...

Tips for effectively sending prop to a component in React with the help of TypeScript

Hey there, I'm working on a component called FormField which can accept either an icon for create or edit. Currently, I am using this FormField inside another component called SelectWithFormField. Here's how it looks: const FormField = ({create, ...

Issue with Angular 6 and Chrome: Event listener ($event) occasionally throws the error "unable to access property 'value' of null"

It appears that the buttons are being iterated correctly using ngFor, and upon inspection they have the correct attributes. However, when clicked, the function in the controller sometimes claims the parameter is 'undefined', happening randomly ab ...

Struggling to update TypeScript and encountering the error message "Unable to establish the authenticity of host 'github.com (192.30.253.113)'"

While attempting to update my version of TypeScript using npm, I ran into an issue when trying to execute the following command: localhost:Pastebin davea$ npm install typescript/2.8.4 --save-dev The authenticity of host 'github.com (192.30.253.113)&a ...

Error type inferred by TypeScript

I am currently in the process of learning TypeScript, and I encountered some errors in the code below: Error: Unexpected token. A constructor, method, accessor, or property was expected. [ts] Declaration or statement expected. class duckType{ public ...

Using React for passing data

In the snippet found in "CameraPage.tsx", there is a logical function that is responsible for fetching camera images. This function simply makes a GET request to search for images stored in the backend, which will later be displayed on the FrontEnd. The op ...

Issue encountered while executing jest tests - unable to read runtime.json file

I've written multiple unit tests, and they all seem to pass except for one specific spec file that is causing the following error: Test suite failed to run The configuration file /Users/dfaizulaev/Documents/projectname/config/runtime.json cannot be r ...

When using the `const { }` syntax, which attribute is made accessible to the external

I am using the ngrx store as a reference by following this example: https://stackblitz.com/edit/angular-multiple-entities-in-same-state?file=src%2Fapp%2Fstate%2Freducers%2Fexample.reducer.ts Within the code in example.reducer.ts, there is this snippet: ...

Select a random class from an array of classes in JavaScript

I have a collection of Classes: possibleEnemies: [ Slime, (currently only one available) ], I am trying to randomly pick one of them and assign it to a variable like this (all classes are derived from the Enemy class): this.enemy = new this.possibleEn ...

After triggering an action, I am eager to make a selection from the store

To accomplish my task, I must first select from the store and verify if there is no data available. If no data is found, I need to dispatch an action and then re-select from the store once again. Here is the code snippet that I am currently using: t ...

How can one retrieve the selected value from a dropdown menu in Angular?

Objective: My goal is to create a dropdown menu where users can select a value, which will then dynamically change the address of the website based on their selection. Issue: Although I managed to make the address change upon selection, it did so for ever ...

Assembly of these elements

When dealing with a structure where each property is of type These<E, A> where E and A are unique for each property. declare const someStruct: { a1: TH.These<E1, A1>; a2: TH.These<E2, A2>; a3: TH.These<E3, A3>; } I inte ...

Mastering ngClass for validation in Angular 2: Step-by-step guide

I am facing an issue with a form I have created where I applied ngclass to display an error when the form value is missing. However, the error is showing up when the form is initially loaded. It seems that by default, my input tag is invalid when the form ...

MUI Select component not displaying top border

Can anyone help me understand why the select field is behaving this way? I'm new to the project and suspect that someone may have made changes to it. <mui.FormControl style={{ width: '598px' }}> <mui.InputLabe ...

In Typescript, what sets apart a generic written before a function compared to after a type declaration?

Can you explain the difference between these two type declarations for arrow functions? export type Sort = <D>(r: Rows<D>, f: Field<D>, o: Order) => Rows<D>; export type Sort<D> = (r: Rows<D>, f: Field<D>, o: ...

The Angular 4 HTTP patch method is encountering difficulties when called in code but functions properly when tested using Post

My attempts to make a patch and post call to the server are failing as it never reaches the server. Interestingly, the same request works flawlessly in Postman, so I suspect there might be an issue with my code. Both my post and patch methods are essentia ...