// 最外层是个函数,再返回一个新的函数 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() );