TypeScript 1.5,反射和装饰器

TypeScript 1.5, reflection and decorator

我想知道是否可以使用反射,更具体地说 class 关于装饰器的反射,属性,参数或方法?

是否可以使用反射器来获取装饰器中使用的信息?

如果可能的话,我们该怎么做? 否则,我们为什么不能这样做?

编辑:

我有一个应用程序,我在其中使用装饰器将数据从 serviceRegistry 注入到名为 @Inject 的装饰器。

在此应用程序中,我手动填写了一个简单的服务注册表,例如:

serviceRegistry.push(MyClass1)
serviceRegistry.push(MyClass2)
...
serviceRegistry.push(MyClass100)

目的是能够在运行时使用用@ToInject 注释装饰的classes 填充此服务注册表。

这将使我能够避免手动填写此注册表,并使其简单地自动化。

感谢预付款

您可以通过导入 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 将其序列化为 class 构造函数
  • 如果 Enum 将其序列化为 Number
  • 如果至少有一个调用签名,序列化为Function
  • 否则序列化为Object(包括接口)

将来可能会通过复杂类型序列化对接口和对象字面量进行序列化,但目前无法使用此功能。

您还可以使用以下函数获取 return 类型的函数:

Reflect.getMetadata("design:returntype", target, key);

如果您需要有关装饰器的更多信息,您可以阅读:Decorators & metadata reflection in TypeScript: From Novice to Expert

我刚刚发布了提供完整反射功能的增强版 TypeScript 编译器:

  • Classes/interfaces 运行时的元数据
  • 从元数据对象实例化classes
  • 从 class 个构造函数中检索元数据

你可以看看here