在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() {
相关推荐
摘星编程4 分钟前
用React Native开发OpenHarmony应用:Calendar日期范围选择
javascript·react native·react.js
东东51625 分钟前
基于vue的电商购物网站vue +ssm
java·前端·javascript·vue.js·毕业设计·毕设
MediaTea30 分钟前
<span class=“js_title_inner“>Python:实例对象</span>
开发语言·前端·javascript·python·ecmascript
雨季6661 小时前
Flutter 三端应用实战:OpenHarmony “微光笔记”——在灵感消逝前,为思想点一盏灯
开发语言·javascript·flutter·ui·dart
编码者卢布1 小时前
【Azure Stream Analytic】用 JavaScript UDF 解决 JSON 字段被转成 Record 的关键点
javascript·json·azure
梦梦代码精1 小时前
开源、免费、可商用:BuildingAI一站式体验报告
开发语言·前端·数据结构·人工智能·后端·开源·知识图谱
0思必得01 小时前
[Web自动化] Selenium执行JavaScript语句
前端·javascript·爬虫·python·selenium·自动化
程序员敲代码吗1 小时前
MDN全面接入Deno兼容性数据:现代Web开发的“一张图”方案
前端
0思必得01 小时前
[Web自动化] Selenium截图
前端·爬虫·python·selenium·自动化
tb_first2 小时前
SSM速通2
java·javascript·后端