I was wondering if it was possible to use reflection, and more particularly class reflection concerning decorator, on property, on parameter or on method ?
Is this possible to use reflector to get the information used in the decorators ?
If it's possible, how can we do that ? Else, why cant we do that ?
EDIT :
I have an application in which I use decorators, to inject data, from a serviceRegistry, to a decorator called @Inject.
In this application, I fill a simple service registry by hand, like :
serviceRegistry.push(MyClass1)
serviceRegistry.push(MyClass2)
...
serviceRegistry.push(MyClass100)
The aim is to be able to fill this service registry with classes that are decorated with @ToInject annotation, at runtime.
This will permit me to avoid to fill this registry by hand, and to automate this simply.
THanks for advance
You can use reflection by importing the reflect-metadata package.
import 'reflect-metadata';
Use it with TypeScript 1.5 and the compiler flag emitDecoratorMetadata
set to true. Don't forget including a reference to reflect-metadata.d.ts
as well.
You need to implement your own decorators:
// declare property decorator
function logType(target : any, key : string) {
var t = Reflect.getMetadata("design:type", target, key);
console.log(`${key} type: ${t.name}`);
}
class Demo{
@logType // apply property decorator
public attr1 : string;
}
It will log in console:
attr1 type: String
Another example:
// declare parameter decorator
function logParamTypes(target : any, key : string) {
var types = Reflect.getMetadata("design:paramtypes", target, key);
var s = types.map(a => a.name).join();
console.log(`${key} param types: ${s}`);
}
class Foo {}
interface IFoo {}
class Demo{
@logParameters // apply parameter decorator
doSomething(
param1 : string,
param2 : number,
param3 : Foo,
param4 : { test : string },
param5 : IFoo,
param6 : Function,
param7 : (a : number) => void,
) : number {
return 1
}
}
It will log in console:
doSomething param types: String, Number, Foo, Object, Object, Function, Function
Notice the that interfaces IFoo
and object literal { test : string}
are serialized as Object
. The serialization rules are:
number
serialized as Number
string
serialized as String
boolean
serialized as Boolean
any
serialized as Object
void
serializes as undefined
Array
serialized as Array
Tuple
, serialized as Array
class
serialized it as the class constructorEnum
serialized it as Number
Function
Object
(Including interfaces)Interfaces and object literals may be serialize in the future via complex type serialization but this feature is not available at this time.
You can also get the return type of a function using:
Reflect.getMetadata("design:returntype", target, key);
If you need more info about decorators you can read : Decorators & metadata reflection in TypeScript: From Novice to Expert