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
我想知道是否可以使用反射,更具体地说 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