您可以通过导入 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