目前装饰器是一项实验性特性,使用可以参照java
启用
- 命令行:tsc –target ES5 –experimentalDecorators
- 在tsconfig.json中的compilerOptions设置:
1
2
3
4
5
6{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
概念
- 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,访问符,属性或参数上。
- 装饰器使用 @expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。
装饰器工厂
1 | const color = (value: string) =>{ //装饰器工厂 |
装饰器组合
- 书写同一行或多行都可:@f
- 当多个装饰器应用于同一个声明上,从上到下,求值的结果从下到上
- 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24function f() {
console.log("f(): evaluated")
return function (target,propertyKey: string, descriptor: PropertyDescriptor) {
console.log("f():called")
}
}
function g() {
console.log("g(): evaluated")
return function (target,propertyKey: string, descriptor: PropertyDescriptor) {
console.log("g():called")
}
}
class C {
method() {}
}
控制台:
f(): evaluated
g(): evaluated
g():called
f():called
装饰器求值
- 参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个实例成员。
- 参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个静态`成员。
- 参数装饰器应用到构造函数。
- 类装饰器应用到类
类装饰器
- 类装饰器在类声明之前被声明(紧靠着类声明)
- 类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。
- 类装饰器不能用在声明文件中(.d.ts),也不能用在任何外部上下文中
- 定义装饰器,在类中应用
- 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Greeter {
greeting: string
constructor(message: string) {
this.greeting = message
}
greet() {
return "Hello," + this.greeting
}
}
function sealed(constructor: Function) {
Object.seal(constructor)
Object.seal(constructor.prototype)
}
方法装饰器 和 访问器装饰器(/后面表示不同其他基本一致)
- 声明在一个方法/访问器的声明之前(紧靠着方法/访问器声明)。
- 会被应用到方法/访问器的属性描述符上,可以用来监视,修改或者替换方法/访问器定义。
- 不能用在声明文件(.d.ts),重载或者任何外部上下文中
- 运行时会当作函数被调用,传入3个参数:
- 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
- 成员的名字
- 成员的属性描述符
- 返回一个值,它会被用作方法的属性描述符。
属性装饰器
- 声明在一个属性声明之前(紧靠着属性声明)。
- 不能用在声明文件中(.d.ts),或者任何外部上下文里
- 运行时当作函数被调用,传入下列2个参数:
- 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
- 成员的名字
参数装饰器
- 声明在一个参数声明之前(紧靠着参数声明)。
- 应用于类构造函数或方法声明。
- 不能用在声明文件中(.d.ts),或者任何外部上下文里
- 运行时当作函数被调用,传入下列3个参数:
- 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
- 成员的名字
- 参数在函数参数列表中的索引
- 只能用来监视一个方法的参数是否被传入,返回值会被忽略。
元数据
- 安装: npm i reflect-metadata –save,
- 启用:
- 命令行:tsc –target ES5 –experimentalDecorators –emitDecoratorMetadata
- 直配置
1
2
3
4
5
6
7
8tsconfig.json:
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
示例
1 | const testDecorator = (xxx: xxx) => { // 创建一个装饰器, 如果有形参则@的表达式也要有形参 |