Typescript 实现一个简单的AOP,后置切面

最近回顾了下AOP——面向切面编程,刚好项目有需要用到,就使用了一下,感觉效果不错,代码贴出来,请拍砖。
主要用到的就是装饰器特性。
主要目的是在实例test.request方法调用后,自动顺序执行components和log方法

export function after(...args) {
  return (_target, name, descriptor) => {
    // 获取value,其实就是request函数
    const oldValue = descriptor.value;
    // 将value重新赋值一个函数
    descriptor.value = async function () {
      // tslint:disable-next-line: no-console
      console.log(`Calling ${name} with`, arguments);
      // 将原本的函数执行一下,apply改变this的指向
      const val = await oldValue.apply(this, arguments)
      let result = val;
      for (const callback of args) {
        result = (await callback(this, result, ...arguments)) || result
      }
      return result;
    };

    return descriptor;
  }
}
export default class Test {
  @after(components, log)
  public async request(url, params) {
    const res = _ajax(url,params); // 异步请求示例
    return res 
  }
}
export function components(target: any, data: any, ...args){
  // target 是 Test对应实例对象
  // data 是每次函数调用返回的结果,第一次接收的是 request 函数返回的值,默认值
  // args 是request函数的参数
}

export function log(target: any, data: any, ...args){
 // 同上,此处data理论上是components返回的值,若components无返回值,则是request返回的默认值
}