前置知识
控制反转与依赖注入
Section titled “控制反转与依赖注入”一般写法
class A { name: string;
// constructor() { // this.name = "A"; // }
// 当构造函数增加参数时,创建实例时必须传入参数,否则会报错,出现了强耦合的问题 constructor(name: string) { this.name = name; }}
class B { a: string;
constructor() { this.a = new A().name; // 报错 }}
class C { a: string;
constructor() { this.a = new A().name; // 报错 }}引入控制反转和依赖注入
class A { name: string;
constructor(name: string) { this.name = name; }}
class B { name: string;
constructor(name: string) { this.name = name; }}
// 依赖注入容器class Container { module: any;
constructor() { this.module = {}; }
provide(key: string, mo: any) { this.module[key] = mo; }
get(key: string) { return this.module[key]; }}
// 创建容器实例const c1 = new Container();// 注册依赖c1.provide("A", new A("Alice"));c1.provide("B", new B("Bob"));
console.log(c1.get("A").name);console.log(c1.get("B").name);
class X { a: any; b: any;
constructor(mo: Container) { this.a = mo.get("A"); this.b = mo.get("B"); }}$ tsc --init// tsconfig.json{ "compilerOptions": { "target": "ES2023", "experimentalDecorators": true, "emitDecoratorMetadata": true }}ClassDecorator 类装饰器
Section titled “ClassDecorator 类装饰器”// targe:构造函数const doc: ClassDecorator = (targe: any) => { console.log("ClassDecorator called on: ", target); // 给A类添加属性 target.prototype.name = "Class A"; // 给A类添加方法 target.prototype.count = (num1: number, num2: number) => { return num1 + num2; };};
// 类装饰器@docclass A { constructor() {}}
// 实例化const a1: any = new A();console.log(a1.name);PropertyDecorator 属性装饰器
Section titled “PropertyDecorator 属性装饰器”const doc: PropertyDecorator = (target: any, propertyKey: string | symbol) => { console.log("PropertyDecorator called on: ", target, propertyKey);};
class A { // 属性装饰器 @doc public name: string;
constructor() { this.name = "Class A"; }}MethodDecorator 方法装饰器
Section titled “MethodDecorator 方法装饰器”const doc: PropertyDecorator = ( target: any, propertyKey: string | symbol, descriptor: any,) => { console.log(target, propertyKey, descriptor: PropertyDecorator);};
const Get = (url: string) => { // 定义方法装饰器 const fn: MethodDecorator = (target, key, descriptor:PropertyDecorator) => { // target: 原型对象 // key: 方法名getList // descriptor: 描述符 console.log(target, key, descriptor); axios.get(url).then(res=>{ descriptor.value(res.data) }) };
return fn;};
class A { public name: string;
constructor() { this.name = "Class A"; }
@doc getName() {}
// 使用方法装饰器 @Get("https://jsonplaceholder.typicode.com/todos") getList(data: any) { console.log(data); }}ParameterDecorator 参数装饰器
Section titled “ParameterDecorator 参数装饰器”const doc: ParameterDecorator = ( target: any, propertyKey: string | symbol | undefined, parameterIndex: number,) => { console.log(target, propertyKey, parameterIndex);};
class A { public name: string;
constructor() { this.name = "Class A"; }
getName(name: string, @doc age: number) {}}todo
todo
装饰器实现NestJS底层GET
Section titled “装饰器实现NestJS底层GET”import axios from "axios";
const Get = (url: string) => { return (target: any, key: any, descriptor: PropertyDecorator) => { const fn = descriptor.value; axios .get(url) .then((res) => { fn(res, { status: 200, success: true, }); }) .catch((e) => { fn(res, { status: 500, success: false, }); }); };};
class Controller { constructor() {}
@Get("/list") getList(res: any, status: any) { console.log(res.data, status); }}