I’ve got an instance where I want to create X number of Classes that all need a constructor to assign a logging service, and then all have a method create
which will handle the data object differently depending on the class.
I then want to pass this class into a function dynamically so that it can be instantiated and the create
method called.
If I try the code below I receive the error TypeError: ContentCreator is not a constructor
, and I can’t find anywhere in the TypeScript documentation to hint at how to pass a class of type extended into a function, and then how to call the constructor to create a new instance.
import { ApplicationLogger } from "application-logger";
interface Logger {}
interface Message {
data: any;
}
class ContentCreator {
logger;
constructor(logger: Logger) {
this.logger = logger;
}
public async create(body: Message): Promise<string[]> {
return new Promise(() => []);
}
}
class PublicationContentCreator extends ContentCreator {
constructor(logger: Logger) {
super(logger);
}
public override async create(body: Message): Promise<string[]> {
console.log("Publication: ", body);
return new Promise(() => []);
}
}
class EventContentCreator extends ContentCreator {
constructor(logger: Logger) {
super(logger);
}
public override async create(body: Message): Promise<string[]> {
console.log("Event: ", body);
return new Promise(() => []);
}
}
function connectAndGetMessage(connectionString: string) {
// ...
}
async function readFromQueue(connectionString: string, ContentCreator: any) {
const logger = new ApplicationLogger();
const creator = new ContentCreator(logger);
const queueData = connectAndGetMessage(connectionString);
creator.create(queueData);
}
(async () => {
await readFromQueue("connection-string", PublicationContentCreator);
})();
2
Answers
So after a lot of digging about (asking Chat-GPT a lot of different combinations) it looks like the key is to type the function parameter as a Constructable Class, which then allows any Class that extends ContentCreator to be passed in and instantiated.
The whole code then looks like this:
The ContentCreator class is an abstract class, so it shouldn’t be instantiated directly. This can be fixed by adding the abstract modifier to the ContentCreator class declaration.
Also, the ContentCreator argument in the readFromQueue() function is not used and can be removed. Instead, the function should be given a concrete class that extends the abstract ContentCreator class. For example, we can pass the PublicationContentCreator class as an argument to the function.
The corrected code would look like this: