在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() {
相关推荐
用户4099322502126 分钟前
FastAPI的查询白名单和安全沙箱机制如何确保你的API坚不可摧?
前端·后端·github
前端小巷子14 分钟前
深入 npm 模块安装机制
前端·javascript·面试
深职第一突破口喜羊羊1 小时前
记一次electron开发插件市场遇到的问题
javascript·electron
cypking1 小时前
electron中IPC 渲染进程与主进程通信方法解析
前端·javascript·electron
西陵1 小时前
Nx带来极致的前端开发体验——借助playground开发提效
前端·javascript·架构
江城开朗的豌豆2 小时前
Element UI动态组件样式修改小妙招,轻松拿捏!
前端·javascript·vue.js
float_六七2 小时前
JavaScript:现代Web开发的核心动力
开发语言·前端·javascript
zhaoyang03012 小时前
vue3笔记(2)自用
前端·javascript·笔记
UrbanJazzerati3 小时前
JavaScript Promise完整指南
javascript
德育处主任Pro3 小时前
# JsSIP 从入门到实战:构建你的第一个 Web 电话
前端