Skip to content

TypeScript 装饰器类型详解

一、类装饰器

typescript
// 参数:类的构造函数
function ClassDecorator(constructor: Function) {
  Object.defineProperty(constructor.prototype, 'timestamp', {
    value: Date.now()
  });
}

@ClassDecorator
class DataService {
  // 装饰后自动添加timestamp属性
}

// 混入示例
function Mixin(...mixins: any[]) {
  return (constructor: Function) => {
    Object.assign(constructor.prototype, ...mixins);
  };
}

二、方法装饰器

typescript
// 参数:target | methodName | descriptor
function ValidateParams(validationRules: any[]) {
  return (target: any, methodName: string, descriptor: PropertyDescriptor) => {
    const original = descriptor.value;

    descriptor.value = function (...args: any[]) {
      args.forEach((arg, index) => {
        if (!validationRules[index](arg)) {
          throw new Error(`参数${index}验证失败`);
        }
      });
      return original.apply(this, args);
    };
  };
}

class UserController {
  @ValidateParams([
    (name: string) => name.length > 3,
    (age: number) => age >= 18
  ])
  createUser(name: string, age: number) {
    // 创建用户逻辑
  }
}

三、属性装饰器

typescript
// 参数:target | propertyName
function DefaultValue(value: any) {
  return (target: any, propertyName: string) => {
    target[propertyName] = value;
  };
}

class FormComponent {
  @DefaultValue('')
  username: string;

  @DefaultValue(0)
  age: number;
}

四、参数装饰器

typescript
// 参数:target | methodName | parameterIndex
function MinLength(min: number) {
  return (target: any, methodName: string, parameterIndex: number) => {
    const original = target[methodName];
    target[methodName] = function (...args: any[]) {
      if (args[parameterIndex].length < min) {
        throw new Error(`参数长度不能少于${min}`);
      }
      return original.apply(this, args);
    };
  };
}

class SearchService {
  search(@MinLength(2) query: string) {
    // 搜索逻辑
  }
}

五、装饰器组合

typescript
// 多个装饰器可以叠加使用
function First() { console.log('first'); }
function Second() { console.log('second'); }

@First
@Second
class MyClass {}

// 输出顺序:second -> first(由内到外执行)