在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() {
相关推荐
Hilaku23 分钟前
前端不懂业务有多可怕?
前端·javascript·程序员
涛涛ing30 分钟前
模型吐出半截JSON,前端如何边收边渲染?2026年AI应用必须闯过的工程关
前端
aixingpan32 分钟前
aixingpan.cnAPI开发文档:api_docs_trichart_natal_solar_return_transit2接口指南
前端·php
FRing031 小时前
JavaScript入门到精通二十八(forEach遍历、创建对象的三种方式、构造函数、new实例化执行过程、实例成员和静态成员)
开发语言·前端·javascript
燕落南枝1 小时前
CSS 表单选择器与伪元素选择器详解
前端·css
拖孩1 小时前
一个人 + AI 做的小程序,今天,正式回本了
前端·后端·微信小程序
进击的丸子1 小时前
APP 人脸识别增值版 SDK:Camera2 无缝接入指南
前端·前端框架·代码规范
进击的丸子1 小时前
代理网络环境下 Linux Pro 在线激活实操指南
javascript·后端·安全
开开心心就好1 小时前
本地文件搜索工具,双击Ctrl就能呼出搜索
java·服务器·前端·支持向量机·ffmpeg·音视频·模拟退火算法
知了清语1 小时前
SVG 缩放预览:F12 无法定位子元素 & 放大模糊
前端