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

Typescript: get class name in its own property at compile time

例如,如果我们有这样的 class:

class MyClass {
  className: string;
}

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

编辑:已尝试 this.constructor.name。但是,后者对缩小代码没有帮助。因此,当打字稿代码被编译为 JS 时,检查是否有办法捕获 class 名称。我正在使用 angular-cli。

/补充回答

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

你说你使用 angular-cli,它在后台使用 UglifyJS 进行丑化。 UglifyJS 支持保留原始 Class 名称的标志,甚至支持应忽略的 class 名称的白名单。具体来说,它是您感兴趣的 mangler 部分。The official website 甚至提到它会使用 Function.name.

破坏代码

您可以完全禁用 mangling,或者您可以专门禁用 mangling class 名称(或将某些 class 名称列入白名单)。我认为 angular-cli 不可能做到这一点(在 webpack 中你可以),但你正在寻找的标志是 keep-classnameskeep_fnames。但是,angular-cli 团队表示 multiple times 不支持这种粒度级别的配置。

那么你似乎还有两个选择:

  1. 切换到完整的 webpack(ng eject 可以帮助你)
  2. 硬编码 class 名称

像这样:

class MyClass {
  className = 'MyClass';
}

什么是 ng 弹出?引用 dave11mj's comment:

ng eject simply means you need to do something a lot more advance or custom with webpack than what the cli provides for commands like ng build and ng serve .. So it generates a webpack.config.js based on the configurations that the cli uses, so that you can then customize it further.

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


/原始答案(在禁用 UglifyJs 处理的情况下仍然有用)

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

const instance = new MyClass();
console.info(instance.className); // yields "MyClass"

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

jsFiddle

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

class MyClass {
  constructor(public className = this.constructor.name) {
    (..)
  }
}

您可以使用构造函数创建一个变量:

constructor() {
  public c : string = this.constructor.name;
}

我知道这现在有点老了,但我 运行 遇到了同样的问题,但找不到好的解决方案。我不想使用 ng eject 来关闭或白名单处理,所以我这样做是为了解决它。我没有使用 this.constructor.name,而是为我创建了一个 return 对象类型的函数。您必须知道您想要哪个 类 并使用 instanceof 运算符在函数中列出它们中的每一个。该函数如下所示:

function getType(o: any):string
{
    if (o instanceof MyClass1)
        return 'MyClass1';
    else if (o instanceof MyClass2)
        return 'MyClass2';
    else
        return null; // class doesn't exist.
}

要使用函数,您可以这样称呼它:

MyClass1 = myClass1;
// instead of this:
console.log(myClass1.constructor.name);
// call this:
console.log(getType(myClass1));

所以在你的情况下,要在编译时运行它,你可以这样做:

class MyClass {
  className: string = getType(this); // or set the value in a constructor
}