Do you know if it is possible to get the array of interfaces implemented by a class using a decorator:
interface IWarrior {
// ...
}
interface INinja {
// ...
}
So If I do something like:
@somedecorator
class Ninja implements INinja, IWarrior {
// ...
}
At run-time Ninja will have an annotation which contains ["INinja", "IWarrior"]
?
Thanks
Currently, types are used only during development and compile time. The type information is not translated in any way to the compiled JavaScript code. But you however can pass the list of strings to the decorator parameter like this:
interface IWarrior {
// ...
}
interface INinja {
// ...
}
interface Function {
interfacesList: string[];
}
@interfaces(["INinja", "IWarrior"])
class Ninja implements INinja, IWarrior {
}
function interfaces(list: string[]) {
return (target: any) => {
target.interfacesList = list;
return target;
}
}
console.log(Ninja.interfacesList);
Since all information about interfaces is thrown away at compile time this will not be possible. There is no way for the implementation of the somedecorator to access information that has been thrown away by the compiler.
Passing the interface names to the decorator as strings is possible, this is however not that useful since all information provided by the interfaces will be gone at run time.
A good stack overflow question about implementing decorators:
How to implement a typescript decorator?
Edit:
So after researching this for a while the answer to your question is still no. For two reasons:
- No information about interfaces can be accessed after compile time (with or without decorators)
- Decorators do not get access to the inherited properties of a class.
Som examples to illustrate this:
function myDecorator() {
// do something here..
}
interface INamed { name: string; }
interface ICounted { getCount() : number; }
interface ISomeOtherInterface { a: number; }
class SomeClass {
constructor() { }
}
class Foo implements INamed {
constructor(public name: string) { }
}
@myDecorator
class Bar extends Foo implements ICounted {
private _count: number;
getCount() : number { return this._count; }
constructor(name: string, count: number, public someProp: ISomeOtherInterface, public someClass: SomeClass) {
super(name);
this._count = count;
}
}
This will result in compiled code (with the --emitDecoratorMetadata flag):
function myDecorator() {
// do something here..
}
var SomeClass = (function () {
function SomeClass() {
}
return SomeClass;
})();
var Foo = (function () {
function Foo(name) {
this.name = name;
}
return Foo;
})();
var Bar = (function (_super) {
__extends(Bar, _super);
function Bar(name, count, someProp, someClass) {
_super.call(this, name);
this.someProp = someProp;
this.someClass = someClass;
this._count = count;
}
Bar.prototype.getCount = function () { return this._count; };
Bar = __decorate([
myDecorator,
__metadata('design:paramtypes', [String, Number, Object, SomeClass])
], Bar);
return Bar;
})(Foo);
Any information that will be available to us in the decorator (except for the class it self) is contained in the __decorate part:
__decorate([
myDecorator,
__metadata('design:paramtypes', [String, Number, Object, SomeClass])
], Bar);
As it stands now no information about inheritance or interfaces are passed along to the decorators. All a decorator for a class does is decorate the constructor. This will probably not change, certainly not for the interfaces (since all information about them gets thrown away at compile time).
As we can se in the type array of the __metadata we get the type information for String, Number and the class SomeClass (constructor arguments). But the interface ISomeOtherInterface is reported as Object, this is because no information about typescript interfaces is retained in the compiled javascript. So the best information we can get is Object.
You can use something like https://github.com/rbuckton/ReflectDecorators to better work with decorators but you will still only be able to access the information in __decorate and __metadata.
So to summarise. No information about inheritance or interfaces for a class is available in a decorator. Interfaces will likely never be available to a decorator (or anywhere else in the compiled code).
来源:https://stackoverflow.com/questions/30188387/using-a-decorator-to-get-list-of-implemented-interfaces