decorator
- Need to enable "experimentalDecorators" in tsconfig.json: true
- Execute sequentially from top to bottom
function setName(){
console.log('get name')
return (target:any)=>{
console.log('set name')
}
}
function setAge(){
console.log('get age')
return (target:any)=>{
console.log('set age')
}
}
@setName()
@setAge()
class A{
}
// get name
// get age
// set age
// set name
class decorator
let sign;
function setName(name:string){
// target就是实例化后的对象
return (target:new ()=>any)=>{
sign=target;
console.log(target.name)
}
}
@setName("jack")
class A{
}
console.log(sign===A)
// true
console.log(sign===A.prototype.constructor)
// true
function addName(constructor:new ()=>any){
constructor.prototype.name='jack'
}
@addName
class B{
}
interface B{
name:string
}
const b=new B();
console.log(b.name)
// jack
decorator function
function classDecorator<T extends new(...args:any[])=>{
}>(target:T){
return class extends target {
public newProperty='new property';
public hello='override'
}
}
@classDecorator
class Greeter {
public Property='property';
public hello:string
constructor(text:string) {
this.hello=text
}
}
console.log(new Greeter('world'))
enum decorator
function enumerable(bool:boolean){
return (target:any,propertyName:string,descriptor:PropertyDescriptor)=>{
console.log(target)
descriptor.enumerable=bool
}
}
class A{
constructor(public age:number) {
}
@enumerable(true)
// 通过传入的值,控制是否可枚举
getAge(){
return this.age;
}
}
const a=new A(18)
for (const key in a) {
console.log(key)
// age getAge
}
- property decorator
function enumerable(target:any,propertyName:string){
console.log(propertyName)
}
class A{
@enumerable
public age:number
constructor(age:number) {
this.age=age
}
}
const a=new A(18)
- parameter decorator
function required(target:any,properName:string,index:number){
console.log(`修饰的是${
properName}的第${
index+1}个参数`)
}
class A{
public name:string='jack';
public age:number=20;
public getInfo(prefix:string,@required infoType:string):any{
return prefix+" "+this[infoType]
}
}
interface A{
[k:string]:string|number|((prefix:string,infoType:string) => void)
}
const a=new A();
a.getInfo('haha','age')
// 修饰的是getInfo的第2个参数
contamination
- Mix the properties and methods of class A and class B, and the returned new class has all the properties of class A and class B
class ClassA{
public isA!:boolean
public funcA(){
}
}
class ClassB{
public isB!:boolean;
public funcB(){
}
}
class ClassAB implements ClassA,ClassB{
public isA:boolean=false;
public isB:boolean=false;
public funcA!:()=>void;
public funcB!:()=>void;
}
function mixins(base:any,from:any[]){
from.forEach((fromItem)=>{
Object.getOwnPropertyNames(fromItem.prototype).forEach(key=>{
// 遍历属性KEY值
base.prototype[key]=fromItem.prototype[key]
})
})
}
mixins(ClassAB,[ClassA,ClassB])
const ab=new ClassAB()
console.log(ab)