北鱼IT

跳至正文
  • 首页
  • PHP
  • 前端
  • 站点地图

typescript 库:reflect-metadata使用

文章索引
  • 一、安装
  • 二、背景
  • 三、目标
  • 四、语法
  • 五、API

npm地址:https://www.npmjs.com/package/reflect-metadata

一、安装

JavaScript
1
npm install reflect-metadata

二、背景

  • 装饰器通过声明式语法在定义类时添加增强类及其成员的能力;
  • 示踪器将注释附加到类的静态属性上;
  • 诸如C#(.NET)和Java之类的语言支持将元数据添加到类型的属性或注释,以及用于读取元数据的反射API。

     

三、目标

  • 许多用例(组合/依赖注入,运行时类型断言,反射/镜像,测试)都希望能够以一致的方式向类中添加其他元数据;
  • 为了使各种工具和库能够推理出元数据,需要一种一致的方法;

  • 产生元数据的修饰器(nee。“ Annotations”)通常需要与可变修饰器组合在一起;

  • 元数据不仅可以用在对象上,也可以通过相关捕获器用在Proxy上;
  • 对开发人员来说,定义新的元数据生成装饰器应该简洁易用;
  • 元数据应该与ECMAScript的其他语言和运行效果一致;

四、语法

运行命令行:tsc index.ts –target ES5 -w –experimentalDecorators –emitDecoratorMetadata

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import 'reflect-metadata'
 
/**
* Declarative definition of metadata
* 元数据的声明式定义
* class C {
*    @Reflect.metadata(metadataKey, metadataValue)
*    method() {}
* }
*/
class C1 {
  @Reflect.metadata('key1', 'value1')
  name: string = 'hello'
 
  @Reflect.metadata('key2', 'value2')
  method() {}
}
 
const value1 = Reflect.getMetadata('key1', new C1(), 'name')
const value2 = Reflect.getMetadata('key2', new C1(), 'method')
console.log('Syntax.1', value1, value2) // value1 value2
 
 
/**
* Imperative definition of metadata
* 元数据的命令式定义
* Reflect.defineMetadata(metadataKey, metadataValue, C.prototype, 'method')
*/
Reflect.defineMetadata('key3', 'value3', C1.prototype, 'name')
 
const value3 = Reflect.getMetadata('key3', C1.prototype, 'name')
console.log('Syntax.2', value3) // value3
 
/**
* Imperative introspection of metadata
* 元数据的命令自省
* let obj = new C()
* let metadataValue = Reflect.getMetadata(metadataKey, obj, 'method')
*/
class A {
  @Reflect.metadata('A-key1', 'A-value1')
  method() {}
}
let obj = new A()
let AMetadataValue1 = Reflect.getMetadata('A-key1', obj, 'method')
console.log('AMetadataValue1', AMetadataValue1)

五、API

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**
* define metadata on an object or property
* 在对象或属性上定义元数据
* Reflect.defineMetadata(metadataKey, metadataValue, target)
* Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey)
*/
class A1 {
  method() {}
}
Reflect.defineMetadata('A1-key1', 'A1-value1', A1)
Reflect.defineMetadata('A1-key2', 'A1-value2', A1, 'method')
 
let A1Result1 = Reflect.getMetadata('A1-key1', A1)
let A1Result2 = Reflect.getMetadata('A1-key2', A1, 'method')
console.log('A1Result1', A1Result1)
console.log('A1Result2', A1Result2)
 
/**
* check for presence of a metadata key on the prototype chain of an object or property
* 检查对象或属性的原型链上是否存在元数据键
* let result = Reflect.hasMetadata(metadataKey, target)
* let result = Reflect.hasMetadata(metadataKey, target, propertyKey)
*/
@Reflect.metadata('c2-key1', 'c2-value1')
class C2 {
  @Reflect.metadata('c2-key2', 'c2-value2')
  name: string = 'bob'
}
 
let c2Result1 = Reflect.hasMetadata('c2-key1', C2) // true
let c2Result2 = Reflect.hasMetadata('c2-key2', C2.prototype, 'name') // true
let c2Result3 = Reflect.hasMetadata('c2-key3', C2.prototype, 'name') // false
console.log('hasMetadata', c2Result1, c2Result2, c2Result3)
 
class C21 extends C2 {
  method() {}
}
let c2Result4 = Reflect.hasMetadata('c2-key1', C21) // true
let c2Result5 = Reflect.hasMetadata('c2-key2', C21.prototype, 'name') // true
console.log('hasMetadata', c2Result4, c2Result5)
 
/**
* check for presence of an own metadata key of an object or property
* 检查对象或属性是否存在自己的元数据键值
* let result = Reflect.hasOwnMetadata(metadataKey, target)
* let result = Reflect.hasOwnmetadata(metadataKey, target, propertyKey)
*/
function age(age: number) {
  console.log('age')
  return function (target: any, propertyKey: string) {
    Reflect.defineMetadata('c3-key3', age, target, propertyKey)
  }
}
 
@Reflect.metadata('c3-key1', 'c3-value1')
class C3 {
  @Reflect.metadata('c3-key2', 'c3-key2')
  name: string = 'bob'
 
  @age(18)
  age: number = 18
}
 
let c3Result1 = Reflect.hasOwnMetadata('c3-key1', C3) // true
let c3Result2 = Reflect.hasOwnMetadata('c3-key2', C3.prototype, 'name') // true
let c3Result3 = Reflect.hasOwnMetadata('c3-key3', C3.prototype, 'age') // true
let c3Result4 = Reflect.hasOwnMetadata('c3-key3', new C3(), 'age') // false
console.log('hasOwnMetadata', c3Result1, c3Result2, c3Result3, c3Result4)
 
class C31 extends C3 {
  method() {}
}
 
let c3Result5 = Reflect.hasOwnMetadata('c3-key1', C31) // false
let c3Result6 = Reflect.hasOwnMetadata('c3-key2', C31, 'name') // false
 
console.log('hasOwnMetadata', c3Result5, c3Result6)
 
/**
* get metadata value of a metadata key on the prototype chain of an object or property
* 在对象或属性的原型链上获取元数据键的元数据值
* let result = Reflect.getMetadata(metadataKey, target)
* let result = Reflect.getMetadata(metadataKey, target, propertyKey)
*/
 
/**
* get metadata value of an own metadata key of an object or property
* 获取对象或属性自己的元数据键的元数据值
* let result = Reflect.getOwnMetadata(metadataKey, target)
* let result = Reflect.getOwnMetadata(metadataKey, target, propertyKey)
*/
 
/**
* get all metadata keys on the prototype chain of an object or property
* 获取对象或属性上所有原型链上的元数据键值
* let result = Reflect.getMetadataKeys(target)
* let result = Reflect.getMetadataKeys(target, propertyKey)
*/
@Reflect.metadata('c4-key2', 'c4-value2')
class C4 {
  @Reflect.metadata('c4-key3', 'c4-value3')
  name: string = 'bob'
 
  @Reflect.metadata('c4-key1', 'c4-value1')
  method() {
    return 'hello'
  }
}
 
let c4Result1 = Reflect.getMetadataKeys(new C4(), 'method')
let c4Result2 = Reflect.getMetadataKeys(C4)
let c4Result3 = Reflect.getMetadataKeys(new C4(), 'name')
let c4Result4 = Reflect.getMetadataKeys(C4.prototype, 'method')
console.log('c4Result1', c4Result1) // [ 'design:returntype', 'design:paramtypes', 'design:type', 'c4-key1' ]
console.log('c4Result2', c4Result2) // [ 'c4-key2' ]
console.log('c4Result3', c4Result3) // [ 'design:type', 'c4-key3' ]
console.log('c4Result4', c4Result4) // [ 'design:returntype', 'design:paramtypes', 'design:type', 'c4-key1' ]
 
class C41 extends C4 {}
let c41Result1 = Reflect.getMetadataKeys(C41)
let c41Result2 = Reflect.getMetadataKeys(C41.prototype, 'method')
console.log('C41Result1', c41Result1) // [ 'c4-key2' ]
console.log('c41Result2', c41Result2) // [ 'design:returntype', 'design:paramtypes', 'design:type', 'c4-key1' ]
 
/**
* get all own metadata keys of an object or property
* 获取对象或属性的所有自有元数据键
* let result = Reflect.getOwnMetadataKeys(target)
* let result = Reflect.getOwnMetadataKeys(target, propertyKey)
*/
@Reflect.metadata('c5-key2', 'value2')
class C5 {
  @Reflect.metadata('c5-key4', 'value4')
  name: string = 'bob'
 
  @Reflect.metadata('c5-key1', 'value1')
  method() {
    return 'hello'
  }
}
let c5Result1 = Reflect.getOwnMetadataKeys(C5.prototype, 'method')
let c5Result2 = Reflect.getOwnMetadataKeys(new C5(), 'method')
let c5Result3 = Reflect.getOwnMetadataKeys(C5)
let c5Result4 = Reflect.getOwnMetadataKeys(C5.prototype, 'name')
let c5Result5 = Reflect.getOwnMetadataKeys(new C5(), 'name')
 
console.log('c5Result1', c5Result1) // [ 'design:returntype', 'design:paramtypes', 'design:type', 'c5-key1' ]
console.log('c5Result2', c5Result2) // []
console.log('c5Result3', c5Result3) // [ 'c5-key2' ]
console.log('c5Result4', c5Result4) // [ 'design:type', 'c5-key4' ]
console.log('c5Result5', c5Result5) // []
 
class C51 extends C5 {}
 
let c51Result1 = Reflect.getOwnMetadataKeys(C51)
console.log('c51Result1', c51Result1) // []
 
/**
* delete metadata from an object or property
* 从对象或属性上删除元数据
* let result = Reflect.deleteMetadata(metadataKey, target)
* let result = Reflect.deleteMetadata(metadataKey, target, propertyKey)
*/

 

本条目发布于2020年12月5日。属于Npm、TypeScript分类,被贴了 metadata、npm、reflect-metadata、typescript 标签。作者是beiyu。

文章导航

← typescript编译Decorators时报错:Unable to resolve signature of method decorator when called as an expression. typescript decorators →
自豪地采用WordPress
  • 公众号

  • 头条号