TypeScript的装饰器简介以及使用方法

TypeScript 的装饰器(Decorators)是一个强大的特性,允许你向类声明、方法、属性或参数添加元数据。装饰器本质上是一个特殊的声明,它能够被附加到类声明、方法、访问符、属性或参数上。装饰器使用 @expression 的形式,expression 必须求值为一个函数,该函数会在运行时被调用,被装饰的声明信息作为参数传入。

装饰器类型

  1. 类装饰器:应用于类声明上。
  2. 方法装饰器:应用于方法上。
  3. 访问符装饰器:应用于 getter/setter 上。
  4. 属性装饰器:应用于属性声明上。
  5. 参数装饰器:应用于参数上。

使用方法

1. 类装饰器
function sealed(constructor: Function) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

@sealed
class Greeter {
  greeting: string;
  constructor(message: string) {
    this.greeting = message;
  }
  greet() {
    return "Hello, " + this.greeting;
  }
}

在这个例子中,sealed 是一个类装饰器,它接收一个构造函数作为参数,并使用 Object.seal 来防止进一步修改构造函数和它的原型。

2. 方法装饰器
function log(target: any, propertyName: string, descriptor: PropertyDescriptor) {
  let originalMethod = descriptor.value;
  descriptor.value = function (...args: any[]) {
    console.log(`Calling ${propertyName} with`, args);
    let result = originalMethod.apply(this, args);
    console.log(`Called ${propertyName}. Result: ${result}`);
    return result;
  };
}

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

const calc = new Calculator();
calc.add(1, 2); // 会在控制台打印日志

log 是一个方法装饰器,它接收三个参数:目标对象、属性名和一个描述符对象。描述符对象可以包含 valuegetsetwritableenumerableconfigurable 属性。在这个例子中,我们修改了 value 属性,用一个新的函数替换了原始方法。

3. 属性装饰器
function autobind(target: any, propertyName: string) {
  let originalValue = target[propertyName];
  Object.defineProperty(target, propertyName, {
    configurable: true,
    enumerable: true,
    get() {
      if (typeof originalValue === 'function') {
        return originalValue.bind(target);
      }
      return originalValue;
    },
    set(value: any) {
      originalValue = value;
    }
  });
}

class App {
  @autobind
  hello() {
    return 'Hello, world!';
  }
}

const app = new App();
const helloFunc = app.hello;
console.log(helloFunc()); // 即使函数是通过属性访问的,也能正确绑定到实例

在这个例子中,autobind 是一个属性装饰器,它接收两个参数:目标对象和属性名。我们使用 Object.defineProperty 来定义一个 getter,这样每次访问 hello 属性时,如果它是一个函数,就会返回一个新绑定的函数。

4. 参数装饰器

参数装饰器只应用于类构造函数的参数上。

function required(target: Object, propertyKey: string | symbol, parameterIndex: number) {
  // 这里你可以根据参数索引做一些事情
}

class MyService {
  constructor(@required private readonly id: string) {}
}

请注意,参数装饰器不能修改参数本身,但可以用来执行一些副作用,如验证或记录参数值。

总结

TypeScript 的装饰器提供了一种声明式的方式来修改类、方法、属性或参数的行为。虽然它们很强大,但应该谨慎使用,以避免过度复杂化代码结构。在大型项目或框架中,装饰器通常用于添加日志、缓存、验证等横切关注点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加仑小铁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值