我想知道是否可以使用反射,尤其是关于装饰器,属性,参数或方法的类反射?
这可以使用反射器来获取装饰器中使用的信息吗?
如果有可能,我们该怎么做? 另外,为什么我们不能这样做?
编辑:
我有一个应用程序,我使用装饰器,从serviceRegistry注入数据到名为@Inject的装饰器。
在这个应用程序中,我手动填写一个简单的服务注册表,如:
serviceRegistry.push(MyClass1)
serviceRegistry.push(MyClass2)
...
serviceRegistry.push(MyClass100)
目的是能够在运行时使用@ToInject批注修饰的类填充此服务注册表。
这将允许我避免手动填写此注册表,并自动完成此操作。
提前谢谢
答案 0 :(得分:12)
您可以通过导入reflect-metadata包来使用反射。
import 'reflect-metadata';
将它与TypeScript 1.5一起使用,并将编译器标志emitDecoratorMetadata
设置为true。不要忘记包括对reflect-metadata.d.ts
的引用。
您需要实现自己的装饰器:
// 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;
}
它将登录控制台:
attr1 type: String
另一个例子:
// 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
}
}
它将登录控制台:
doSomething param types: String, Number, Foo, Object, Object, Function, Function
请注意,接口IFoo
和对象文字{ test : string}
被序列化为Object
。序列化规则是:
number
序列化为Number
string
序列化为String
boolean
序列化为Boolean
any
序列化为Object
void
序列化为undefined
Array
序列化为Array
Tuple
,则序列化为Array
class
将其序列化为类构造函数Enum
将其序列化为Number
Function
Object
(包括接口)接口和对象文字可能会在未来通过复杂类型序列化进行序列化,但此功能目前不可用。
您还可以使用以下方法获取函数的返回类型:
Reflect.getMetadata("design:returntype", target, key);
如果您需要有关装饰器的更多信息,请阅读:Decorators & metadata reflection in TypeScript: From Novice to Expert
答案 1 :(得分:0)