随着TypeScript和ES6里引入了类,在一些场景下我们需要额外的特性来支持标注或修改类及其成员。 装饰器(Decorators)为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式。
tsconfig.json
{
"compilerOptions":
{
"target": "ES5",
"experimentalDecorators": true
}
}
装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
declare type ParameterDecorator = (target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => void;
类装饰器 ClassDecorator
const doc:ClassDecorator = (target:Function)=>{
console.log(target)
target.prototype.name = "zgy"
}
@doc
class A{
constructor(){
}
}
const a:any = new A()
console.log(a.name)
属性装饰器 PropertyDecorator
const doc:PropertyDecorator = (target: Function, propertyKey:string | symbol): void => {
console.log(target, propertyKey);
};
class A {
@doc
name: string
constructor(name) {
this.name = name;
}
}
const a: any = new A("zgy");
方法装饰器 MethodDecorator
const doc: MethodDecorator = (
target: Object,
propertyKey: string | symbol,
descriptor: PropertyDescriptor
): PropertyDescriptor | void => {
console.log(target, propertyKey, descriptor);
};
class A {
name: string;
constructor(name) {
this.name = name;
}
@doc
getName() {
return this.name;
}
}
const a: any = new A("zgy");
属性装饰器 ParameterDecorator
const doc: ParameterDecorator = (
target: Object,
propertyKey: string | symbol | undefined,
parameterIndex: number
): void => {
//parameterIndex =1 参数的下标
console.log(target, propertyKey, parameterIndex);
};
class A {
name: string;
constructor(name) {
this.name = name;
}
getName(a:string,@doc b:string) {
return this.name+a+b;
}
}
const a: any = new A("zgy");
a.getName("你好","世界")
Demo 封装axios Get Post装饰器
本示例采用NestJS
demo.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class DemoService {
getList(){
return [
{
title:'小张',
id:1
},
{
title:'小明',
id:2
},
{
title:'小红',
id:3
},
]
}
update(){
return {
code:200,
message:'ok'
}
}
}
demo.controller.ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
} from '@nestjs/common';
import { DemoService } from './demo.service';
@Controller('demo')
export class DemoController {
constructor(private readonly demoService: DemoService) {}
@Get('list')
getList() {
return this.demoService.getList();
}
@Post('update')
update(@Body() updateData) {
return this.demoService.update();
}
@Post('agreement')
getXieyiBody(@Body() body) {
let agreement = body.agreement
.replace(/\*\*\*\*\*/, '')
.replace(/&&&&&/, '');
const list = agreement.split('@');
let address = Number(list[0])
.toString(16)
.toLocaleUpperCase()
.padStart(2, '0');
let stakeMark = list[1];
let orderCode = list[2];
let data = list[3];
console.log(
`地址:${address},桩号:${stakeMark},执行码:${orderCode},数据:${data}`,
);
}
}
ts文件 装饰器的demo
import axios from 'axios'
const Get = (url:string) => {
return (
target: Object,
propertyKey: string | symbol,
descriptor: PropertyDescriptor
): PropertyDescriptor | void => {
const fn = descriptor.value;
axios
.get(url)
.then((res) => {
fn({
code:200,
data:res.data,
success:"ok"
})
})
.catch((err) => {
fn({
code:500,
data:null,
success:"err"
})
});
};
};
const Post = (url:string) => {
return (
target: Object,
propertyKey: string | symbol,
descriptor: PropertyDescriptor
): PropertyDescriptor | void => {
const fn = descriptor.value;
axios
.post(url)
.then((res) => {
fn(res.data)
})
.catch((err) => {
fn({
code:500,
data:null,
success:"err"
})
});
};
};
class A {
constructor() {}
@Get("http://localhost:3000/demo/list")
getList(data) {
console.log("getList",data)
}
@Post("http://localhost:3000/demo/update")
update(data){
console.log("update",data)
}
}