Typescript:在编译时在自己的属性中获取类名

时间:2018-01-25 08:35:29

标签: typescript angular-cli uglifyjs

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

class MyClass {
  className: string;
}

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

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

4 个答案:

答案 0 :(得分:3)

/其他答案

由于即使在uglifying之后你需要原始类的实际名称,你需要调查你的构建过程。

你说你使用的是angular-cli,它使用了UglifyJS来进行丑化。 UglifyJS支持一个标志,用于保留原始类名,甚至是应该忽略的类名白名单。具体来说,你感兴趣的是 mangler 部分。The official website甚至提到它会使用Function.name来破解代码。

您可以完全禁用修改,或者您可以专门禁用修改类名(或白名单某些类名)。我不认为这可以使用angular-cli(在webpack中你可以),但你要找的标志是keep-classnameskeep_fnames。但是,angular-cli团队已指出multiple times它不支持此粒度级别的配置。

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

  1. 切换到完整的网络包(ng eject可以帮助您)
  2. 硬编码班级名称
  3. 像这样:

    class MyClass {
      className = 'MyClass';
    }
    

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

      

    ng eject 只是意味着您需要使用webpack做更多事情或自定义,而不是cli为ng build和ng服务等命令提供的东西。所以它生成了一个webpack.config。 js基于cli使用的配置,以便您可以进一步自定义它。

    因此,只要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) {
        (..)
      }
    }
    

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

您可以使用constructor获取课程名称

Class MyClass {
  className: string;
}

在构造函数

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

答案 3 :(得分:0)

我知道现在有点老了,但我遇到了同样的问题,无法找到一个好的解决方案。我不想使用ng弹出关闭或白名单修改,所以我这样做是为了解决它。我没有使用this.constructor.name创建了一个函数来为我返回对象类型。您必须知道所需的类,并使用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
}