本篇文章将在上篇文章类的装饰器基础之上,介绍关于类的标准装饰器。
定义类的标准装饰器
当用装饰器扩展了类的行为(属性、方法)后,在用装饰器类的时候是无法提示我们为类添加的新属性的。
为了解决这一问题,延伸出了类的标准装饰器,类的标准装饰器写法如下:
function testDecorator<T extends new (...args: any[]) => {}>(constructor: T) { }
@testDecorator
class Test2{ }
const test2 = new Test2()
下面针对标准装饰器的参数泛型来拆解说明:
(...args:any[]) => {}
: 定义函数,接收多个参数,参数类型是any,返回值为一个对象
new (...args:any[]) => {}
: 能够用 new 关键字,说明 (...args:any[]) => {}
代表的是一个构造函数
extends new (...args:any[]) => {}
: 能够使用 extends 关键字,说明new (...args:any[]) => {}
代表的是一个构造函数的类。
标准装饰器修饰类的构造函数
可以在装饰器中修饰一个类的构造函数。
class extends constructor
表示一个装饰器修饰的类的构造函数,可以对类的构造函数进行扩展。
function testDecorator<T extends new (...args: any[]) => {}>(constructor: T) {
return class extends constructor {
name = 'lee'
}
}
@testDecorator
class Test2{
name:string
constructor() {
this.name = 'Test2'
}
}
const test2 = new Test2()
自身构造函数和装饰器修饰的类构造函数的执行顺序是先执行自身构造函数再执行装饰器修饰的构造函数。
扩展类的构造函数
装饰器可以对一个类进行扩展,例如为类添加新的属性和方法等。
function testDecorator() {
return function<T extends new (...args: any[]) => any>(constructor: T) {
return class extends constructor {
name = 'lee'
getName() {
return this.name
}
}
}
}
const Test2 = testDecorator()(
class {
name: string;
constructor(name: string) {
this.name = name;
}
}
);
调用 testDecorator()
函数会返回一个装饰器修饰的类,已经装饰过后的类就证明已经有了getName
方法,TypeScript 语法就可以识别出getName()
是可用的。