打字稿:在编译时在自己的属性中获取类名

cyn*_*ynx 7 uglifyjs typescript angular-cli

例如,如果我们有一个这样的类:

class MyClass {
  className: string;
}
Run Code Online (Sandbox Code Playgroud)

是否可以在编译时将“MyClass”分配给 className 属性?

编辑:已经尝试过 this.constructor.name。但是,后者对缩小代码没有帮助。因此检查是否有办法在将 typescript 代码编译为 JS 时捕获类名。我正在使用 angular-cli。

Ben*_*ema 7

/附加答案

由于即使在丑化之后您也需要原始类的实际名称,因此您需要查看您的构建过程。

你说你使用 angular-cli,它在引擎盖下使用 UglifyJS 进行丑化。UglifyJS 支持保留原始类名的标志,甚至是应该忽略的类名白名单。具体是你感兴趣的mangler部分。官方网站甚至提到它会破坏代码使用Function.name.

您可以完全禁用修改,或者您可以专门禁用修改类名(或将某些类名列入白名单)。我认为 angular-cli 无法做到这一点(在 webpack 中可以),但是您要查找的标志是keep-classnameskeep_fnames。然而,angular-cli 团队已经多次指出也不会在这个粒度级别支持配置。

那么你似乎有两个选择:

  1. 切换到完整的 webpack(ng 弹出可以帮助你)
  2. 硬编码类名

像这样:

class MyClass {
  className = 'MyClass';
}
Run Code Online (Sandbox Code Playgroud)

什么是 ng 弹出?引用dave11mj 的评论

ng 弹出只是意味着你需要用 webpack 做一些比 cli 为 ng build 和 ng serve 等命令提供的更高级或自定义的事情。所以它会根据 cli 使用的配置生成一个 webpack.config.js,以便您可以进一步自定义它。

因此,只要 angular-cli 本身不支持 UglifyJS 的配置,这听起来肯定是为您的情况而设计的。


/ 原始答案(在禁用 UglifyJs 重整时仍然有用)

class MyClass {
  className = this.constructor.name;
}

const instance = new MyClass();
console.info(instance.className); // yields "MyClass"
Run Code Online (Sandbox Code Playgroud)

如果您使用 TypeScript >= 2.1,string则编译器会推断类型。

js小提琴

如果你有一个构造函数,你也可以像这样定义它并完全省略显式字段(偏好问题,两者的工作方式相同):

class MyClass {
  constructor(public className = this.constructor.name) {
    (..)
  }
}
Run Code Online (Sandbox Code Playgroud)