# 装饰器

# 开启装饰器

// tsconfig.json
{
  // ...
  "experimentalDecorators": true
}
  • 类似于语法糖
@decorator
class A {}

// 等同于
class A {}
A = decorator(A) || A

# 类装饰器

  • 装饰器函数的第一个参数就是所要装饰的目标类
function decorator(target): ClassDecorrator {
  target.prototype.test = 'hello world'
}

// 可以使用参数
function testDecorator(msg) {
  return function (target) {
    target.prototype.test = msg
  }
}

@decorator('hello typescript')
class Say {}

const a = new Say()
a.test // 'hello typescript'

# 方法装饰器

  • target: 当前的类
  • name: 使用装饰器的方法的名称
  • descriptor: 属性描述符,重写 value 属性可以改变函数的功能
function debounce(wait): MethodDecorator {
  return function(target, name, descriptor) {
    descriptor.value = debounce(descriptor.value, wait)
  }
}

class A {
  @debounce(100)
  sayHello() {
    console.log('hello')
  }
}

# 属性装饰器

function propDeco(target, key): PropertyDecorator {
  console.log(key) // testProp
}

class Test {
  @propDeco
  testProp: any
}

# 参数装饰器

// index 为当前参数所在第几位
function argDeco(target, key, index): ParameterDecorator {
  console.log(key)
  console.log(index)
}

class Test {
  method(@argDeco() param1: string) {
    console.log(param1)
  }
}

# 装饰器的顺序

function foo() {
  console.log('foo in')
  return function () {
    console.log('foo out')
  }
}

function bar() {
  console.log('bar in')
  return function () {
    console.log('bar out')
  }
}

// ...
@foo()
@bar()
method() {}
// ...
// foo in
// bar in
// bar out
// foo out