装饰器在TypeScript里,说白了就是一种特殊类型的声明,能附加到类、方法、属性或者参数上,用来修改或者扩展它们的行为。它本质上是个函数,在代码运行时自动被调用,有点像给目标元素"贴标签",然后执行一些额外的逻辑。TypeScript从早期版本就开始支持装饰器,不过得在tsconfig.json里开启experimentalDecorators选项才能用。装饰器用起来语法很简单,就是在目标前加个@符号,后面跟个函数名。比如,@log这样的形式,就能轻松给方法添上日志功能。
先说说类装饰器,它是最常用的一种。类装饰器接收一个参数,就是类的构造函数。你可以在里头改原型、加属性,甚至返回个新的构造函数来彻底替换掉原来的。举个例子,假设你想给所有类自动加个版本号,可以写个装饰器函数,在里头给类原型上挂个version属性。这样,每个用这个装饰器的类,就自带版本信息了,不用手动一个个去写。
方法装饰器也挺实用的,它主要针对类里的方法。它能拿到三个参数:类的原型、方法名,还有方法的属性描述符。通过属性描述符,你可以控制方法能不能修改、枚举,或者直接重写方法逻辑。比如,工作中经常需要给某些方法加权限检查,你可以写个@checkPermission装饰器。在里头判断用户角色,如果没权限就抛出错误,否则才放行。这样,代码看起来干净多了,业务逻辑和权限控制分得清清楚楚。
属性装饰器和参数装饰器相对用得少点,但也有它们的用武之地。属性装饰器能修饰类的属性,你可以用它来自动初始化值或者加个类型检查。参数装饰器则用在方法的参数上,比如结合依赖注入框架,自动解析参数类型。不过这些高级用法,得结合实际项目来细琢磨。
装饰器在实际开发里能玩出很多花样。比如,结合元数据反射,可以实现AOP(面向切面编程),把日志、事务管理这些横切关注点抽离出来。再比如,在Web框架里,用装饰器定义路由,像@Get('/users')这样,代码读起来特别直观。不过要注意,装饰器的执行顺序是从上到下、从外到里,类装饰器先于方法装饰器执行,这点容易踩坑,写的时候得留心。
当然,装饰器也不是万能药。用多了可能会让代码更难调试,因为逻辑分散在多个地方。另外,如果装饰器里干了太重的活儿,比如异步操作,可能会影响性能。所以,建议在简单场景下用,复杂的话还是得权衡一下。总之,TypeScript装饰器是个强大工具,用对了能大大提升代码的可维护性,下次写项目时不妨试试看,说不定有惊喜。