TypeScript 1.5,反射和装饰器

时间:2015-06-05 03:58:35

标签: typescript typescript1.5

我想知道是否可以使用反射,尤其是关于装饰器,属性,参数或方法的类反射?

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

如果有可能,我们该怎么做? 另外,为什么我们不能这样做?

编辑:

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

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

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

目的是能够在运行时使用@ToInject批注修饰的类填充此服务注册表。

这将允许我避免手动填写此注册表,并自动完成此操作。

提前谢谢

2 个答案:

答案 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)

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

  • 运行时的类/接口元数据
  • 从元数据对象实例化类
  • 从类构造函数中检索元数据

您可以查看here