typescript装饰器一文搞懂

TS装饰器

概括

是 ES7 的一个新语法

本质是一种函数,可以附加到类,方法,属性,参数上,用来提供元数据或者修改类

提供了一种声明式的方式去修改类的结构和行为,使代码更清晰、易于理解

需要在 ts 项目的tsconfig.json 中启用实验性装饰器支持:

1
2
3
4
5
6
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}

分类

  1. 类装饰器

  2. 属性装饰器

  3. 方法装饰器

  4. 参数装饰器

  5. 访问器装饰器(get & set)

实现原理

  1. 定义装饰器函数:定义一个装饰器函数,接收一个或多个参数,对目标对象进行相应改造

  2. 应用装饰器:使用@将装饰器应用到类、方法、属性等声明之前,ts编译器遇到会调用装饰器函数,并将目标对象作为参数传递给装饰器函数

  3. 执行装饰器函数:根据传入的目标对象进行一些操作,例如添加元数据、修改对象的行为或结构等。装饰器函数可以返回一个新的对象,也可以直接修改目标对象

装饰器语法

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
// 类装饰器
const myClass: ClassDecorator = (target: Function) => {
target---类的构造函数
}
// 方法装饰器
const myFunction: MethodDecorator = (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
target---类的实例
propertyKey---方法名
descriptor---方法描述(value、writable、enumetable、configurable)
}
// 属性装饰器
const myProperty: PropertyDecorator = (target: any, propertyKey: string | symbol) => {
target---类的实例
propertyKey---属性名
}
// 参数装饰器
const myParameter: ParameterDecorator = (target: any, propertyKey: string | symbol, parameterIndex: number) => {
target---类的实例
propertyKey---方法名
parameterIndex---方法参数索引
}

@myClass
class MyClass {
@myProperty
myProperty: string = 'Hello';

@myFunction
myMethod(@myParameter param: string): void {
console.log('Method called');
}
}

向装饰器传参

借助函数科里化

1
2
3
4
5
const decorator = (param) => {
return (target, propertyKey?, descriptor?) => {
// do something with param and target
}
}

执行顺序

(参数装饰器 ==> 方法装饰器)|| 属性装饰器 ==> 类装饰器

  • 方法装饰器和属性装饰器按照声明顺序执行
  • 多个参数装饰器从后向前执行
  • 类装饰器最后执行

使用场景

  • 使用 class-validatorclass-transformer 等库,可以结合装饰器进行参数和类型的验证和转换
  • NestJSAngular 框架广泛使用装饰器实现依赖注入、定义路由、请求方法、中间件等
  • ORM 库(如 TypeORM)中,装饰器用于定义实体和表结构,以及属性与数据库字段的映射关系

总结

  • 装饰器对类的改造是编译时进行的,而不是运行时

  • 多个装饰器可以组合使用,链式调用

  • 装饰器不仅增强了代码的可读性和可维护性,还提供了强大的功能扩展能力


typescript装饰器一文搞懂
http://47.95.158.220/2024/06/03/decorator/
作者
akkwei
发布于
2024年6月3日
许可协议