Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何以编程方式在Typescript中创建类函数?_Typescript - Fatal编程技术网

如何以编程方式在Typescript中创建类函数?

如何以编程方式在Typescript中创建类函数?,typescript,Typescript,我有一个日志类,它需要定义各种方便的函数,例如error,warn,info,等等,所有这些函数都做相同的事情:调用log函数及其严重性和要记录的数据 这是冗长的,浪费了KBs: class Logger { error(...args: any[]): void { this.log('error', ...args) } warn(...args: any[]): void { this.log('warn', ...args) } // ...and s

我有一个日志类,它需要定义各种方便的函数,例如
error
warn
info
,等等,所有这些函数都做相同的事情:调用
log
函数及其严重性和要记录的数据

这是冗长的,浪费了KBs:

class Logger {
  error(...args: any[]): void {
    this.log('error', ...args)
  }
  warn(...args: any[]): void {
    this.log('warn', ...args)
  }
  // ...and so on
}
我目前拥有所有严重性的枚举,以及所有严重性字符串的并集:

enum severityLevels {
  error,
  warn,
  info
}

type severities = keyof typeof severityLevels
const severityKeys =
  Object.keys(SeverityLevels).filter(k => k !== (+k) + "") as Severities[];
我想做的是在logger类的构造函数(vanilla JS中非常简单的
Object.keys(severityLevels).forEach(…)
)中以编程方式为每个严重性级别创建函数,但是我不知道如何让TypeScript允许这种情况发生。如果我创建了一个包含所有严重性函数定义的接口,我就无法
实现它(函数还不存在)。如果我让它们成为可选的,那么调用那些日志函数(可能“不存在”)就会变得混乱


有什么想法吗?

您可以通过编程将方法添加到JavaScript中的构造函数的
原型中,从而添加到TypeScript中。棘手的部分是让类型系统理解您正在做什么,这是可行的,但需要一些技巧

首先,让我们列出这些严重性的实际运行时列表:

enum severityLevels {
  error,
  warn,
  info
}

type severities = keyof typeof severityLevels
const severityKeys =
  Object.keys(SeverityLevels).filter(k => k !== (+k) + "") as Severities[];
注意,根据TS惯例,I init将类型大写为
严重级别
严重级别
。还请注意,TypeScript中的数值
enum
对象也具有反向映射:
严重性。错误
0
严重性[0]
“错误”
。为了只获得键的列表,我必须用
k!==(+k)+“

然后,让我们制作一个示例
BaseLogger
类,该类表示记录器的功能,而不使用添加的方法:

class BaseLogger {
  constructor(public loggerName: string) {

  }
  log(level: string, ...args: any[]) {
    console.log("[" + this.loggerName + "]", "[" + level + "]", ...args);
  }
}
下面是我们可以如何进行编程扩展:

type Logger = BaseLogger & Record<Severities, (...args: any) => void>;
const Logger = (
  class Logger extends BaseLogger { }
) as new (...args: ConstructorParameters<typeof BaseLogger>) => Logger;
severityKeys.forEach(k => Logger.prototype[k] = function (this: Logger, ...args: any) {
  this.log(k, ...args);
})
我觉得不错。好吧,希望有帮助;祝你好运


为什么不使用一个单独的日志函数来接收severityLevel枚举?只需使用详细版本即可。gzip之后有效负载大小的差异将是微不足道的。冗余是您为类型安全性付出的代价。你也可以试试。哇,不错!用于学习的书签。昨天(对我来说)有两个棘手的打字问题,这一个仍然没有答案,如果你想尝试一下的话…在那里添加了一个答案(有警告)