打字稿:在编译时在自己的 属性 中获取 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-classnames
或 keep_fnames
。但是,angular-cli 团队表示 multiple times 不支持这种粒度级别的配置。
那么你似乎还有两个选择:
- 切换到完整的 webpack(ng eject 可以帮助你)
- 硬编码 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
。
如果你有一个构造函数,你也可以这样定义它并完全省略显式字段(偏好问题,两者工作相同):
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
}
例如,如果我们有这样的 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-classnames
或 keep_fnames
。但是,angular-cli 团队表示 multiple times 不支持这种粒度级别的配置。
那么你似乎还有两个选择:
- 切换到完整的 webpack(ng eject 可以帮助你)
- 硬编码 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
。
如果你有一个构造函数,你也可以这样定义它并完全省略显式字段(偏好问题,两者工作相同):
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
}