🗒️TypeScript 5.0 装饰器

type
status
date
slug
summary
tags
category
icon
password
URL
装饰器在 TS 中的作用非常重要,它可以帮助我们简化代码、增加功能,提高代码重用性和可维护性。
类装饰器用于修饰类,可以添加额外的行为或者修改类的行为。它可以用于在类声明之前对类进行拦截、修改或者扩展,对类进行修饰。类装饰器的使用场景很多,比如日志记录、性能分析、权限控制等。
方法装饰器用于修饰类的方法,可以在方法定义之前对方法进行拦截、修改或者扩展。它可以用于验证输入、记录日志等场景。
TypeScript 5.0 以前的版本里,装饰器是基于装饰器ECMAScript Stage-2 提案实现的。装饰器ECMAScript Stage-3 提案通过后,新版本的装饰器已经在 TypeScript 5.0 中正式推出,不再需要编译器标志experimentalDecorators,并遵循官方 ECMAScript Stage-3 提案。
 

TypeScript 5.0 以前装饰器代码片段

typescript

function debugMethod(_target: unknown, memberName: string, propertyDescriptor: PropertyDescriptor) { return { get() { const wrapperFunction = (...arguments_: unknown[]) => { const now = new Date(Date.now()); console.log('start time', now.toISOString()); propertyDescriptor.value.apply(this, arguments_); const end = new Date(Date.now()); console.log('end time', end.toISOString()); }; Object.defineProperty(this, memberName, { value: wrapperFunction, configurable: true, writable: true, }); return wrapperFunction; }, }; } class ComplexClass { @debugMethod public complexMethod(_a?: number): void { console.log("DOING STUFF!"); } }
TypeScript

json

{ "compilerOptions": { "strict": true, "experimentalDecorators": true, "target": "ES2017", "jsx": "react", "module": "ESNext", "moduleResolution": "node" } }
JSON
tsconfig.json

TypeScript 5.0 装饰器代码片段

typescript

function debugMethod<This, Args extends any[], Return>( originalMethod: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return> ) { const methodName = String(context.name); function replacementMethod(this: This, ...args: Args) { const now = new Date(Date.now()); console.log(`${methodName} start time`, now.toISOString()); const result = originalMethod.call(this, ...args); const end = new Date(Date.now()); console.log(`${methodName} end time`, end.toISOString()); return result; } return replacementMethod; } class ComplexClass { @debugMethod complexMethod(_a?: number): void { console.log("DOING STUFF!"); } } new ComplexClass().complexMethod()
TypeScript
 

装饰器应用顺序

简言之,规律是,由外往内存下装饰器,如果是装饰器工厂的话就求值,然后由内往外调用装饰器。
 

typescript

function kkk(str:string) { console.log(`装饰器工厂 求值 @kkk(): ${str}`); return ( value:any, context:any ) => console.log(`装饰器应用 @kkk(): ${str}`) } function jjj(value: any, context: any) { return console.log(`装饰器应用 @jjj() ${context.name}`) } function log(str:string) { console.log(str); return str; } @kkk('类装饰器') class T { @kkk('静态属性装饰器') @jjj static staticField = log('静态属性值'); @kkk('原型方法') @jjj [log('计算方法名')]() {} @kkk('实例属性') instanceField = log('实例属性值'); @kkk('静态方法装饰器') static fn(){} }
TypeScript
应用的顺序:

plain

[LOG]: "装饰器工厂 求值 @kkk(): 类装饰器" [LOG]: "装饰器工厂 求值 @kkk(): 静态属性装饰器" [LOG]: "装饰器工厂 求值 @kkk(): 原型方法" [LOG]: "计算方法名" [LOG]: "装饰器工厂 求值 @kkk(): 实例属性" [LOG]: "装饰器工厂 求值 @kkk(): 静态方法装饰器" [LOG]: "装饰器应用 @kkk(): 静态方法装饰器" [LOG]: "装饰器应用 @jjj() 计算方法名" [LOG]: "装饰器应用 @kkk(): 原型方法" [LOG]: "装饰器应用 @jjj() staticField" [LOG]: "装饰器应用 @kkk(): 静态属性装饰器" [LOG]: "装饰器应用 @kkk(): 实例属性" [LOG]: "装饰器应用 @kkk(): 类装饰器" [LOG]: "静态属性值"
Plain text

更多阅读:

 

© black-black-cat 2021-2025