Typescript decorator

装饰器执行时机

修饰器对类的行为的改变,是代码编译时发生的(不是TypeScript编译,而是js在执行机中编译阶段),而不是在运行时。这意味着,修饰器能在编译阶段运行代码。也就是说,修饰器本质就是编译时执行的函数。
在Node.js环境中模块一加载时就会执行

编译ts文件

tsc test1.ts –target ES5 –experimentalDecorators

类装饰器

1.参数为构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Path(path: string) {
return function(targer: Function) {
!targer.prototype.config && (targer.prototype.config = {})
targer.prototype.config.baseUrl = path;
}
}

@Path('/url')
class Service {
constructor(){}
}

console.log((<any>Service.prototype).config) // { baseUrl: '/url' }
let service = new Service()
console.log((<any>service).config) // { baseUrl: '/url' }

方法装饰器

1.静态方法是构造函数,成员函数是类的原型对象
2.成员的名字
3.成员的属性描述符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Get(path: string): any {
return function(targer, methodName: string, descriptor: PropertyDescriptor) {
!targer.config && (targer.config = {})
targer.config[methodName] = path;
}
}

class Service {
@Get('user')
getUser() {}

constructor(){}
}

console.log((<any>Service.prototype).config) // { getUser: 'user' }
let service = new Service()
console.log((<any>service).config) // { getUser: 'user' }

Get 的返回值要为any,否则tsc编译时候报错: Unable to resolve signature of method decorator when called as an expression

方法参数装饰器

1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
2、参数的名字。
3、参数在函数参数列表中的索引。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function PathParam(path: string) {
return function(target, paramName: string, index: number) {
!target.config && (target.config = {})
target.config[index] = path;
}
}

class Service {
getUser(@PathParam('userID') userid: string, @PathParam('userName') name: string) {}

constructor(){}
}

console.log((<any>Service.prototype).config) // { '0': 'userID', '1': 'userName' }

属性装饰器

1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
2、成员的名字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function DefaultValue(value: string) {
return function(target, propertyName: string) {
!target.config && (target.config = {})
target.config[propertyName] = value;
}
}
class Service {

@DefaultValue("0")
value: string

constructor(){}
}

console.log((<any>Service.prototype).config) // { value: '0' }

装饰器加载顺序

1、有多个参数装饰器时:从最后一个参数依次向前执行

2、方法和方法参数中参数装饰器先执行。

3、类装饰器总是最后执行。

4、方法和属性装饰器,谁在前面谁先执行。因为参数属于方法一部分,所以参数会一直紧紧挨着方法执行

Author: Rick
Link: https://rcrick.github.io/2020/03/31/Typescript-decorator/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶