在TypeScript中装饰器有哪些应用场景?

markdown 复制代码
# TypeScript装饰器应用场景详解

## 1. 类装饰器
```typescript
function logClass(target: Function) {
  console.log(`Class ${target.name} was defined`);
}

@logClass
class MyClass {
  // 类实现
}

应用场景:

  • 类注册(如Angular的@Component)
  • 类扩展(添加元数据)
  • 类替换(修改构造函数)

2. 方法装饰器

typescript 复制代码
function logMethod(
  target: any,
  propertyKey: string,
  descriptor: PropertyDescriptor
) {
  const originalMethod = descriptor.value;
  
  descriptor.value = function(...args: any[]) {
    console.log(`Calling ${propertyKey} with args: ${args}`);
    return originalMethod.apply(this, args);
  };
}

class Calculator {
  @logMethod
  add(a: number, b: number) {
    return a + b;
  }
}

应用场景:

  • 日志记录
  • 性能监控
  • 权限控制
  • 缓存处理

3. 属性装饰器

typescript 复制代码
function format(formatString: string) {
  return function(target: any, propertyKey: string) {
    let value = target[propertyKey];
    
    const getter = () => value;
    const setter = (newVal: string) => {
      value = newVal.replace(/(\d{4})(\d{2})(\d{2})/, formatString);
    };
    
    Object.defineProperty(target, propertyKey, {
      get: getter,
      set: setter
    });
  };
}

class User {
  @format('$1-$2-$3')
  birthDate: string;
}

应用场景:

  • 数据格式化
  • 数据验证
  • 属性监听
  • 依赖注入

4. 参数装饰器

typescript 复制代码
function validateParam(
  target: Object,
  propertyKey: string | symbol,
  parameterIndex: number
) {
  // 存储参数验证信息
  const validations = Reflect.getMetadata('validations', target) || [];
  validations.push({
    method: propertyKey,
    paramIndex: parameterIndex,
    validator: (value: any) => value > 0
  });
  Reflect.defineMetadata('validations', validations, target);
}

class MathService {
  sqrt(@validateParam value: number) {
    return Math.sqrt(value);
  }
}

应用场景:

  • 参数验证
  • 依赖注入(如Angular)
  • 参数转换

5. 访问器装饰器

typescript 复制代码
function configurable(value: boolean) {
  return function(
    target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor
  ) {
    descriptor.configurable = value;
  };
}

class Point {
  private _x: number;
  private _y: number;
  
  constructor(x: number, y: number) {
    this._x = x;
    this._y = y;
  }
  
  @configurable(false)
  get x() { return this._x; }
  
  @configurable(true)
  get y() { return this._y; }
}

应用场景:

  • 访问控制
  • 属性配置
  • 计算属性缓存

6. 装饰器工厂

typescript 复制代码
function unit(unitName: string) {
  return function(target: any, propertyKey: string) {
    const units = Reflect.getMetadata('units', target) || {};
    units[propertyKey] = unitName;
    Reflect.defineMetadata('units', units, target);
  };
}

class Physics {
  @unit('m/s²')
  acceleration: number;
  
  @unit('kg')
  mass: number;
}

应用场景:

  • 带参数的装饰器
  • 元数据标记
  • 配置驱动

7. 元数据反射

typescript 复制代码
import 'reflect-metadata';

function entity(name: string) {
  return function(target: Function) {
    Reflect.defineMetadata('entity', name, target);
  };
}

@entity('user')
class User {
  // 类实现
}

// 获取元数据
const entityName = Reflect.getMetadata('entity', User);

应用场景:

  • ORM映射
  • API文档生成
  • 序列化配置

8. 组合装饰器

typescript 复制代码
function first() {
  console.log('first(): factory evaluated');
  return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log('first(): called');
  };
}

function second() {
相关推荐
duanshu_31 分钟前
官网表单与下载异常怎么排查?五个环节定位故障
前端·自动化·flyweight
Zhou1411361 小时前
SpringBoot_03_Web开发
前端·spring boot·python
辻弋2011 小时前
【无标题】
大数据·服务器·前端·搜索引擎·开源软件
FluxArt2 小时前
GPT Image 2.5 中文提示词教程:Flux Art 可复用模板
前端·gpt·算法
搬砖的小码农_Sky2 小时前
AI Agent:Windows上Node.js安装后 npm -v报错
前端·npm·node.js·人机交互
计算机魔术师3 小时前
半年翻倍!OpenAI再融300亿,估值冲到1.4万亿
前端
研☆香3 小时前
jQuery + Swiper.js 实现动态渲染轮播图
前端·javascript·jquery
子兮曰4 小时前
Node.js 50个优势场景盘点:一个人单干,为啥我多数时候只用它
前端·后端
IT_陈寒4 小时前
我花3小时debug,就因为JavaScript这个隐式转换坑
前端·人工智能·后端
excel4 小时前
Nuxt 中 useSeoMeta 与 useHead 的区别
前端