简体   繁体   中英

How to hint types for class methods that are dynamically created?

I have following class:

const LOG_LEVELS = ['error', 'warn', 'info', 'debug'];

class Logger {
  log (level, message) {
    // some code for logging
  }
}

for (const LEVEL of LOG_LEVELS) {
  Logger.prototype[LEVEL] = function(message) {
    this.log(LEVEL, message);
  }
}

I want to type hint above code with typescript.

I have tried the following:

const LOG_LEVELS = ['error', 'warn', 'info', 'debug'];

class Logger {
  public [key in LOG_LEVELS]: (message: string) => void;

  public log (level: string, message: string): void {
    // some code for logging
  }
}

for (const LEVEL of LOG_LEVELS) {
  Logger.prototype[LEVEL] = function (message: string): void {
    this.log(LEVEL, message);
  };
}

But I got "A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type" inside class definition and "Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Logger'" on the prototype extension.

What is the correct way to type hint dynamically added class methods? Is it possible to achieve type hint without defining all the log level methods explicitly?

I'm using typescript 3.5.3.

You can use interface/class merging to merge a mapped type into the class. If we use as const in the log levels we get all the methods as expected:


const LOG_LEVELS = ['error', 'warn', 'info', 'debug'] as const;
interface Logger extends Record<typeof LOG_LEVELS[number], (message: string) => void> {}
class Logger {
  public log (level: string, message: string): void {
    // some code for logging
  }
}

for (const LEVEL of LOG_LEVELS) {
  Logger.prototype[LEVEL] = function (message: string): void {
    this.log(LEVEL, message);
  };
}


new Logger().error("") // ok 

Play

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM