"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

Exploring deep nested components and elements in Angular for a targeted specific functionality

Is it possible to apply the ng deep css class to only one specific checkbox in my component, rather than all checkboxes? I want to customize just one checkbox and leave the others unchanged. How can this be achieved? Thank you. I need the CSS modificatio ...

The system now alerts that there are no pending migrations when trying to execute them, which previously ran smoothly without any issues

I am experiencing an issue with my web app where the migrator I have written to create tables and relations is not being recognized by TypeORM, preventing it from running. Here is a glimpse of my file structure (specifically the migrations): src> Data ...

Initiate and terminate server using supertest

I've developed a server class that looks like this: import express, { Request, Response } from 'express'; export default class Server { server: any; exp: any; constructor() { this.exp = express(); this.exp.get('/' ...

unable to utilize a tip with d3 version 5 in a TypeScript environment?

i'm facing an issue with the following code snippet: var tip = d3.tip() .attr('class', 'd3-tip') .attr('id', 'tooltip') .html(function(d) { return d; }) .direction('n ...

Retrieve the output of a function in TypeScript

I'm encountering a challenge with returning a string instead of a function in an object value. Currently, an arrow function is returning an array of objects, and one of them needs to conditionally change a value based on the input value. Here is the ...

In Angular, encountering difficulty accessing object members within an array when using custom pipes

Here is a custom pipe that I have created, but I am facing an issue accessing the members of the customfilter array, which is of type Item. import { Pipe, PipeTransform } from '@angular/core'; import {Bus} from '/home/pavan/Desktop/Pavan ...

The Concept of Static Block in TypeScript

For the purpose of testing Network Encoding/Decoding Logic, I have implemented a pair of test cases in both Java and JavaScript. These tests utilize Data Providers which essentially consist of various Constants. In my Java test case, I have a Data Provide ...

What is the best way to duplicate a Typescript class object while making changes to specific properties?

I have a Typescript cat class: class Kitty { constructor( public name: string, public age: number, public color: string ) {} } const mittens = new Kitty('Mittens', 5, 'gray') Now I want to create a clone of the inst ...

Saving in prettier differs from running it with npm

./file.ts (INCORRECT) import { jwtGroupClaimToRolesDomain, ScopeIds } from '@invison/shared'; import { Injectable, NestMiddleware } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { Response } fro ...

The presence of HttpInterceptor within a component is causing a ripple effect on all of the App

I am encountering an issue with a library I have that includes a component. This component has an HttpInterceptor that adds a header to each of its requests. The problem arises when I use the component in another project - the HttpInterceptor ends up addi ...

NextImage encountering issues in Internet Explorer 11

In my TypeScript setup, here is a snippet from my package.json file: "dependencies": { "@tailwindcss/typography": "^0.4.1", "@webcomponents/shadydom": "^1.7.4", "cookie": "^0.4.1", " ...

Asserting types for promises with more than one possible return value

Struggling with type assertions when dealing with multiple promise return types? Check out this simplified code snippet: interface SimpleResponseType { key1: string }; interface SimpleResponseType2 { property1: string property2: number }; inter ...

Type narrowing is ineffective for discriminated unions in most cases

Consider the type definition provided below: type A = { a: string } | { a?: undefined; b: string } This essentially means that if you include a, it should be the only property provided. If you do not include or have a as undefined, then you also need to p ...

What is the process for integrating unit tests from external sources into an Angular project following an upgrade to version 15

As of Angular v15, the require.context function has been removed from the test.ts configuration file. I used to rely on require.context to expose tests outside of the Angular project to Karma. Now that it's no longer available: const contextGlobal = ...

Versatile Typescript options

Is it possible to enforce a value to be within a list using TypeScript with enums? Can this be achieved with TypeScript type definitions? enum Friend { JOHN, SALLY, PAUL, } type MyFriends = { friends: Friend[], bestFriend: <> //How ca ...

Using Typescript in combination with snowpack may result in nullish coalescing operators being generated when targeting a version lower than ES2020

I've been working on compiling my TypeScript code/packages to ensure compatibility with Safari Version less than 14. After researching, I discovered that nullish coalescing operators (??) are not allowed in the targeted version. Despite changing my t ...

typescript unconventional syntax for object types

As I was going through the TypeScript handbook, I stumbled upon this example: interface Shape { color: string; } interface Square extends Shape { sideLength: number; } var square = <Square>{}; square.color = "blue"; square.sideLength = 10; ...

Struggling to bring in components in ReactJS

My journey with ReactJS has just begun, and I've encountered some issues with the code that I believe should work but doesn't. To start off, I set up a new ReactJS project using the npm command create-react-app. Following this, I installed Googl ...

Error: The property '...' is not found in the ReactElement<any, any> type, but it is required in the type '{...}'

As a beginner in TypeScript, I am currently working on rendering a page by fetching data from getStaticProps. The code snippet I am using for this purpose is: import React, {FormEvent, useState} from "react"; import { InferGetStaticPropsType } fr ...

Implement Stripe API mocking using Jest in Node.js with Typescript

I'm having trouble simulating the Stripe API for testing purposes. Although I don't have much experience with mocking functions using jest, I've already extensively researched how to mock the Stripe API without success. My file structure is ...