Search code examples
typescriptclassdefaultfunction-call-operator

How to declare default-function for a class?


The Function Call Operator in C++ allows a class to act like it were a function. I have used it in a logging class where something like this:

logger.setFileName("./debug.log");
logger.log("Log this message");

turns into this:

logger.setFileName("./debug.log");
logger("Log this message");

And now I would like to use Function Call Operator or something in that direction in type-script (to provide a default-function for my class), but how do we achieve such a declaration in type-script?

Should we rather make a feature request at GitHub?


Solution

  • This would need to be a JavaScript proposal.

    You can't make a JavaScript class that behaves like this, but you can make a regular function that acts like that, though it takes some gymnastics:

    interface Logger {
      (message: string): void;
      setFileName(filename: string): void;
    }
    
    const logger = function (message: string) {
    
    } as Logger;
    
    logger.setFileName = function (filename: string) {
    
    }
    
    logger.setFileName("./debug.log");
    logger("Log this message");
    

    Edit: here's an example that uses a createLogger() factory function to create multiple instances with state stored in function scope:

    interface Logger {
      (message: string): void;
      setFileName(filename: string): void;
    }
    
    const createLogger = (): Logger => {
      let _filename: string;
      const logger = function (message: string) {
        console.log(_filename, message);
      } as Logger;
    
      logger.setFileName = function (filename: string) {
        _filename = filename;
      }
    
      return logger;
    }
    
    const logger1 = createLogger();
    const logger2 = createLogger();
    logger1.setFileName("./debug1.log");
    logger2.setFileName("./debug2.log");
    logger1("one");
    logger2("two");
    
    // Output:
    // ./debug1.log one
    // ./debug2.log two