For example if we have a class like this:
class MyClass {
className: string;
}
Is it possible to get 'MyClass' assigned to className property at compile time?
EDIT: already tried this.constructor.name. However, latter doesnt help with minified code. Hence checking if there is a way to capture class name when typescript code is compiled to JS. I'm using angular-cli.
Use the name property on an object's constructor to get the class name of the object, e.g. const className = e1.constructor.name . The constructor property returns a reference to the constructor function that created the object.
The class in TypeScript is compiled to plain JavaScript functions by the TypeScript compiler to work across platforms and browsers. A class can include the following: Constructor. Properties. Methods.
Abstract classes are base classes from which other classes may be derived. They may not be instantiated directly. Unlike an interface, an abstract class may contain implementation details for its members. The abstract keyword is used to define abstract classes as well as abstract methods within an abstract class.
TypeScript offers full support for the class keyword introduced in ES2015. As with other JavaScript language features, TypeScript adds type annotations and other syntax to allow you to express relationships between classes and other types.
/additional answer
Since you need the actual name of the original class even after uglifying, you will need to look into your build process instead.
You say you use angular-cli, which uses UglifyJS under the hood for uglifying. UglifyJS supports a flag for keeping the original Class names, or even a whitelist of class names that should be ignored. Specifically it is the mangler portion you are interested in. The official website even mentions it will break code using Function.name
.
You can completely disable mangling, or you can specifically disable mangling class names (or white list certain class names). I don't think this is possible with angular-cli (in webpack you can), but the flag you are looking for is keep-classnames
or keep_fnames
. However, the angular-cli team has indicated multiple times it won't support configuration on this granular level.
So then you have two options left it seems:
Like so:
class MyClass {
className = 'MyClass';
}
What is ng eject? Quoting 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.
So it certainly sounds like it was made for your case as long as angular-cli doesn't natively support configuration for UglifyJS.
/original answer (still useful with UglifyJs mangling disabled)
class MyClass {
className = this.constructor.name;
}
const instance = new MyClass();
console.info(instance.className); // yields "MyClass"
If you use TypeScript >= 2.1, the type string
is inferred by the compiler.
jsFiddle
If you have a constructor anyway, you can also define it like this and omit the explicit field completely (matter of preference, both work the same):
class MyClass {
constructor(public className = this.constructor.name) {
(..)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With