TypeScript 类的装饰器2

// 最外层是个函数,再返回一个新的函数
function testDecorator(flag: boolean) {
  if (flag) {
    return function (constructor: any) {
      constructor.prototype.getName = () => {
        console.log('dell');
      }
    }
  } else {
    return function (constructor: any) { }
  }
}

// 执行下这个函数,跟上面不包含的效果是一样 的
@testDecorator(true)
class Test{ }

const test = new Test();
(test as any).getName();

 

这个装饰器有一个缺点,就是原型中加了 getName 方法,下面 text. 点不出来 getName 方法,所以接下来解决这个问题
这里的参数是 any 类型不对,这个构造器就是构造函数类型
/**
 * 装饰器
 * @param constructor 
 * (...args: any[]) => {} 这是一个函数,返回一个对象,接收的参数是任意个,任意类型组成的数组
 * new 代表这是一个构造函数
 */
// function testDecorator<T extends new (...args: any[]) => {}>(constructor: T) {
//   return class extends constructor{
//     name = 'lee';
//     getName() {
//       return this.name;
//     }
//   }
// }
// class Test{ 
//   name: string;
//   constructor(name: string) {
//     this.name = name;
//   }
// }
// const test = new Test('dell');

/**
 * 这个时候外层 test. 还是点不出来,因为 class Test 下面没有 getName,
 * 而是 testDecorator 里面偷偷装饰的,ts 解析不出来,接下来我们的装饰器要换种写法
 */
function testDecorator() {
  return function <T extends new (...args: any[]) => {}>(constructor: T) {
    return class extends constructor{
      name = 'lee';
      getName() {
        return this.name;
      }
    }
  }
}

/**
 * testDecorator() 返回一个装饰器,返回的装饰器去装饰 class 
 * 这个 class 就有了 getName 这个函数
 */
const Test = testDecorator()(class { 
    name: string;
    constructor(name: string) {
      this.name = name;
    }
  }
)


const test = new Test('dell');
console.log( test.getName() );

 

 

posted @ 2020-08-03 08:32  wzndkj  阅读(147)  评论(0编辑  收藏  举报