0

I don't know how to type a variable to contain a derived class that will be instantiated when needed.

// I have a base class... abstract class Base { constructor() { console.log("Base"); } abstract fun(); } // ...for various derived classes class Derived extends Base { constructor() { super(); console.log("Derived"); } fun() { console.log("Have fun") } } // Now I want to collect the derived classes in an array... interface OneNode { handler: Base; // What should I put here? Obviously if I put "any" don't have complains } const availableNodes: OneNode[] = [ {handler: Derived} // Here ts complains that "Property 'fun' is missing in type 'typeof Derived' but required in type 'Base'. ts(2741)" ] // ...and instantiate some of them only when needed const y = new availableNodes[0].handler(); // Here ts complains that "This expression is not constructable. Type 'Base' has no construct signatures. ts(2351)" y.fun(); 

If I ignore the TypeScript complains or type the "handler" field as "any", everything works as expected. But I want to properly type the "handler" variable.

2
  • Did you mean {handler: new Derived()}? You are assigning the class itself, not an instance. A class is not an instance of itself nor its parent. const node: OneNode = Derived will fail the same way. const node: OneNode = new Derived() will work just fine. Commented Nov 18, 2024 at 15:52
  • 1
    You're looking for new() => Base as shown in this playground link. Does that fully address the question? If so then I'll write an answer (or, more likely, find a duplicate). If not, then what's missing? Commented Nov 18, 2024 at 15:53

1 Answer 1

1

Well, it depends on if you are trying to create an array of the constructors or of objects?

  • It sounds like you want to create an array of constructors, so type Handler as {new (): Base}. This is type of a constructor.
  • If you want to create an array of objects, instead of writing Derived in the object of type OneNode, write new Derived().

Working code:

// Now I want to collect the derived classes in an array... interface OneNode { handler: { new (): Base }; } const availableNodes: OneNode[] = [{ handler: Derived }]; // ...and instantiate some of them only when needed const y = new (availableNodes[0]?.handler)(); y.fun(); 

Source for a list of constructors solution: https://stackoverflow.com/a/13408029/2834938

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @eli! Your first solution works like a charm. Cannot apply the 2nd because the various derived class constructors do things and need a parameter known only later.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.