Preventing me from instantiating objects

I've been struggling with an issue for a while now

consider the following:

export abstract class abstractClass {
    abstract thing(): string
}

export class c1 extends abstractClass {
    thing(): string {
        return "hello"
    }
}

export class c2 extends abstractClass {
    thing(): string {
        return "world"
    }
}

export interface simpleInter {
    el: typeof abstractClass
}

const cls: simpleInter[] = [];
cls.push({
    el: c1
},{
    el: c2
})

for (const classObj of cls) {
    const c = new (classObj.el)() // error: Cannot create an instance of an abstract class. ts(2511)
    console.log(c.thing())
}

What baffles me is how can I instruct the compiler to recognize that I want classes which extend my abstractClass as the type.

Answer №1

To ensure proper implementation of your concrete classes, define a constructor function interface called CConstructor and use it as the base type instead of typeof abstractClass. By following this approach, you will be on the right track.

export interface CConstructor {
    new(): abstractClass
}

export abstract class abstractClass {
    abstract thing(): string
}

export class c1 extends abstractClass {
    thing(): string {
        return "greetings"
    }
}

export class c2 extends abstractClass {
    thing(): string {
        return "universe"
    }
}

const cls: CConstructor[] = [c1, c2];

for (const classObj of cls) {
    const c = new (classObj)()
    console.log(c.thing())
}

Update:

The presence of new(): abstractClass within CConstructor denotes a "Construct Signature," which can be created by prefixing a call signature with the keyword new. For further details, refer to the new TS handbook page.

Answer №2

It seems like you are looking to dynamically instantiate your classes. If you need more information on this topic, you can refer to: Dynamic instantiation in JavaScript

For autocompletion, you can cast later to the desired object.

I'm not entirely sure if this will solve your problem, but it might bring you closer to a solution:

interface simpleInter {
  el: string;
}

const cls: simpleInter[] = [];
cls.push({
  el: 'c1'
},{
  el: 'c2'
});

function instantiate(className: string, args: any) {
  var o, f, c;
  c = window[className]; // get reference to class constructor function
  f = function(){}; // dummy function
  f.prototype = c.prototype; // reference same prototype
  o = new f(); // instantiate dummy function to copy prototype properties
  c.apply(o, args); // call class constructor, supplying new object as context
  o.constructor = c; // assign correct constructor (not f)
  return o;
}

for (const classObj of cls) {
  const c = instantiate(classObj.el, []); // error: Cannot create an instance of an abstract class. ts(2511)
  console.log(c.thing());
}

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

Setting the root directory and output directory can be a bit tricky when dealing with source code scattered across multiple folders. Here's

Utilizing TypeScript in my Node.js project, I previously had a directory structure that looked like this: node_modules src -Models -Routes -Middlewares -Controllers -index.ts package.json tsconfig.json In ...

deliver a promise with a function's value

I have created a function to convert a file to base64 for displaying the file. ConvertFileToAddress(event): string { let localAddress: any; const reader = new FileReader(); reader.readAsDataURL(event.target['files'][0]); reader ...

Is there a way to retrieve the attributes of a generic object using an index in TypeScript?

I'm currently working on a function that loops through all the attributes of an object and converts ISO strings to Dates: function findAndConvertDates<T>(objectWithStringDates: T): T { for (let key in Object.keys(objectWithStringDates)) { ...

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 ...

When canActivate returns false, the screen in Angular 2 will still be accessed

I am encountering a problem where my canActivate method is returning false, but still navigating to the blocked screen. This issue seems to only occur in Chrome, as everything works fine in IE. Here is how the canActivate method looks: canActivate(route: ...

Can getters and setters be excluded from code coverage reports in Angular projects?

Looking to clean up my coverage reports for the front end portion of an angular project by removing trivial code like getters and setters. I generate my reports using npm run test-sonar -- --coverage, but everything is included in the report when I view ...

Exploring NuxtJS Vuex Module namespaces and mutation enumerations

My NuxtJS website has a Vuex store with a root state and a module located at store/shop/cart/state.ts. Within the module, there is a file called store/shop/cart/mutations.ts. import { MutationTree } from 'vuex'; import { CartState } from './ ...

The attribute is not found on the combined type

After combing through various questions on stackoverflow, I couldn't find a solution to my specific case. This is the scenario: interface FruitBox { name: string desc: { 'orange': number; 'banana': number; } } interf ...

How can I integrate a timer into an Angular carousel feature?

I have put together a carousel based on a tutorial I found on a website. Check out the HTML code for my carousel below: <div class="row carousel" (mouseover)="mouseCheck()"> <!-- For the prev control button ...

Put an end to the endless game of defining TypeScript between Aurelia CLI and Visual Studio 2017 builds

I am encountering TypeScript errors in my Visual Studio build for an Aurelia project within a .NET Core project. The errors include 'Build:Cannot find name 'RequestInit'', 'Build:Cannot find name 'Request'', and &apo ...

Mastering the art of utilizing GSI Index and FilterExpression in AWS DynamoDB querying

In my DynamoDB database table, I have the following structure. It consists of a primary key (ID) and a sort key (receivedTime). ID(primary key) receivedTime(sort key) Data ID1 1670739188 3 ID2 167072 ...

What steps can be taken to resolve the issue of receiving the error message "Invalid 'code' in request" from Discord OAuth2?

I'm in the process of developing an authentication application, but I keep encountering the error message Invalid "code" in request when attempting to obtain a refresh token from the code provided by Discord. Below is a snippet of my reques ...

Rollup faces challenges when trying to bundle source code alongside Bazel and Typescript

I am attempting to create a bundle using rollup, typescript, and bazel environment. I am having trouble importing relative paths. Typescript builds correctly but rollup is unable to bundle the source. WORKSPACE # WORKSPACE workspace( name = "WORK ...

Angular project icons not displaying in the browser

My current project in Angular was functioning properly until recently. I am facing an issue where the images are not being displayed on the browser when I run ng serve, resulting in a 404 error. Interestingly, everything else seems to be working fine witho ...

Is there a way to fetch a particular object from Firebase database based on its value using AngularFire2?

Here is the database I am working with: firebase database I am trying to retrieve a dish that has its 'featured' attribute set to true (dish.feature = true). Is it possible to do this directly from the database, or do I have to retrieve all di ...

Reasons behind Angular HttpClient sorting JSON fields

Recently, I encountered a small issue with HttpClient when trying to retrieve data from my API: constructor(private http: HttpClient) {} ngOnInit(): void { this.http.get("http://localhost:8080/api/test/test?status=None").subscribe((data)=> ...

Determine the type and create an instance of a fresh class

In my app, I have a function that handles all API requests. Any interaction I make goes through this function. I'm trying to set a specific return type for this function, but the return type is of a class. In order to use the methods of this class, I ...

Is there a way to determine if a React functional component has been displayed in the code?

Currently, I am working on implementing logging to track the time it takes for a functional component in React to render. My main challenge is determining when the rendering of the component is complete and visible to the user on the front end. I believe t ...

constrain a data structure to exclusively contain elements of a particular data type

interface Person { id:number, name:string } const someFunction(people: ???) => {...} Query: Can the people parameter be typeguarded to only allow an object with all properties matching a Person interface, similar to the following structure: pe ...

Challenges with Loading JSON Dynamically in Next.js using an NPM Package

In my TypeScript project, I have implemented a functionality where a json configuration file is dynamically loaded based on an enum value passed as a parameter to the getInstance function in my PlatformConfigurationFactory file. public static async getIn ...