How to declare typescript type of module that supports both being called as a function and instantiated as a class

Viewed 39

I'm trying to write a typescript type definition for a 3-rd party javascript npm module that allows being used as a function or as a class (with new). Using it looks something like this:

functionOrClass(arg1, arg2)

or (at the same time)

var instance = new functionOrClass(configParam)
 
instance.method(arg1, arg2)

I'd expect the module declaration to be something like the following (except that the last line doesn't work)

declare module 'module-name' { 
   declare function functionOrClass(                                                                 
     arg1: number, arg2?: number                                                            
   ): string;                                                                                         
                                                                                                      
   declare class FunctionOrClass {                                                                            
     constructor(config?: Record<string, any>)                                                                    
                                                                                                      
     method: functionOrClass;                                                                    
   }; 

   export functionOrClass | FunctionOrClass;
}

It feels like a problem that many people must have solved before, but I probably lack the terminology to be able to Google for it. Please help me how to define this.

1 Answers

This is possible in TypeScript with call signatures and construct signatures:

class T {}

declare const callAsClassOrFunction: {
    new (...args: any[]): T;
    (...args: any[]): any;
};

new callAsClassOrFunction();

callAsClassOrFunction();

In this example the constructor returns an instance of whatever class T, while calling it as a normal function returns anything you want (but could also be T).

Playground

Related