TypeScript 装饰器

TypeScript 装饰器

代码来自后盾网

装饰器为 ts 提供了强大的代码复用功能

使用装饰器需要在 tsconfig.json 中修改

装饰器是试验性的功能,需要在配置文件中开启

json
{
  "experimentalDecorators": true,
  "emitDecoratorMetadata": true,
}

类装饰器 ClassDecorator

相当于在原型对象上添加属性

类装饰器只有一个参数,是构造函数。

ts
const moveDecorator: ClassDecorator = (target: () => void) => {
    console.log(target)
    target.prototype.getPosition = (): { x: number, y: number } => {
        return { x: 20, y: 20 }
    }
}

@moveDecorator
class Player {}

@moveDecorator
class Tank {}

const player = new Player()
console.log(player.getPosition())

装饰器语法糖 @

不使用语法糖,需要传递类到对应的函数中。使用语法糖不需要手动调用。

装饰器叠加

可以使用多个装饰器

实例:全局消息响应

装饰器工厂

根据不同的条件返回不同的装饰器

方法装饰器

可以使用函数装饰器更改函数的内容

ts
const ShowDecorator: MethodDecorator = (...args: any[]) => {
    console.log(args)
    args[2].value = () => {
        console.log("ShowDecorator changed")
    }
}
class User {
    @ShowDecorator
    public show() {
        console.log("show function ")
    }
}

new User().show() // 打印 "ShowDecorator changed",函数内容已经被更改

上面那样使用数组接收后调用不是很直观,我们可以使用变量名接收方法装饰器参数

const ShowDecorator: MethodDecorator = (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => { ... };

调用装饰器时,也可以更改静态方法的内容

调用 writable = true 控制方法不能重新声明

示例:模拟代码高亮

可以先使用变量将函数内容保存起来,在自定义操作后直接调用保存的函数

示例:结合装饰器工厂实现延迟执行

示例:全局异常处理

示例:根据权限限制访问

可以根据传入的权限数组进行判断用户是否有访问权限

属性装饰器

接收的参数

  • args0: target 静态参数就是构造函数,普通参数就是其原型对象
  • args1: propertyKey 属性名称
  • args2: undefined
ts
const PropDecorator: PropertyDecorator = (target: object, propertyKey: string | symbol) => {
    console.log(target, propertyKey)
}
class User {
    public username: string
}

实例:使用属性装饰器动态改变对象属性

将属性改为全部大写

参数装饰器

接收的参数

  • args0: target 静态参数就是构造函数,普通参数就是其原型对象
  • args1: propertyKey 属性名称
  • args2: parameterIndex 参数所在的位置,从 0 开始计数
ts
const ParamDecorator: ParameterDecorator = (target: object, propertyKey: string | symbol, parameterIndex: number) => {
    console.log(target, propertyKey, parameterIndex)
}
class User {
    show(id: number, @ParamDecorator user: { name: string }) {}
}

装饰器执行顺序:

参数装饰器 -> 方法装饰器

TypeScript 命名空间
TypeScript interface和type

评论区

评论加载中...