类装饰器
装饰器本身是一个函数,该函数有一个参数,参数本身是该类(构造函数)
使用装饰器
@装饰器
在TS中,如何约束一个变量为类
-
Function
-
new(参数)=>object
在TS中使用装饰器,要配置"experimentalDecorators": true,
装饰器函数的运行是在类定义之后就马上运行。
装饰器在编译后存在,本身是js存在的语法
类装饰器可以具有的返回值
- void:仅运行函数
- 返回一个新的类:会将新的类替换掉装饰目标
function test(target:new()=>object){
return class B extends target{
}
}
@test
class A{
}
const a = new A();
console.log(a); //B {}
- 解读
首先装饰器可以用到其它类,类装饰器可以增强类的功能。
上面例子,test装饰器返回一个B类,类A使用装饰器test,那么a对象就是B类创建出来的,这样就可以增强A类的功能。
但是存在一个问题,就是类型检查问题
function test(target:new()=>object){
return class B extends target{
}
}
//这里就会报错,因为a对象是B对象产生的但是没有类型约束。
@test
class A{
props1:string
}
const a = new A();
console.log(a); //B {}
如何约束类的构造函数的参数有几个
//使用剩余参数
function test(target:new(...args:any[])=>object){
return class B extends target{
}
}
@test
class A{
constructor(props1:string,props2:string){
}
}
const a = new A('str0','str1');
- 类装饰器另外一种写法
function test(str:string){
return function test(target:new(...args:any[])=>object){
}
}
@test('这是一个类')
class A{
constructor(props1:string,props2:string){
}
}
多个装饰器的运行顺序
type constructor = new(...args:any[])=>object;
function d1(target:constructor){
console.log('d1');
}
function d2(target:constructor){
console.log('d2');
}
@d1
@d2
class A{
}
运行结果是:d2 d1
,所以从下往上运行。
- 面试题
type constructor = new(...args:any[])=>object;
function d1(){
console.log('d1');
return function(target:constructor){
console.log('d1 decorator');
}
}
function d2(){
console.log('d2');
return function(target:constructor){
console.log('d2 decorator');
}
}
@d1()
@d2()
class A{
}
// 'd1' 'd2' 'd2 decorator' 'd1 decorator'