×

了解一个TS基础应用:TypeScript 中的装饰器

作者:abc1232023.10.07来源:Web前端之家浏览:1217评论:0
关键词:Typescript

从我记事起,装饰器几乎就已经是 ECMAScript 的一部分了。这些漂亮的工具让我们能够以可重用的方式修改类和成员。他们已经在 TypeScript 中出现了一段时间——尽管是在实验旗帜下。尽管装饰器的第 2 阶段迭代始终处于实验阶段,但装饰器已广泛应用于MobXAngularNestTypeORM等库中。TypeScript 5.0 的装饰器与ECMAScript 提案完全同步,ECMAScript 提案已经为黄金时段做好了准备,处于第 3 阶段。

装饰器让我们可以设计一个函数来调整类及其方法的行为。想象一下需要将一些调试语句潜入我们的方法中。在 TypeScript 5.0 之前,我们必须在每个方法中手动复制和粘贴调试语句。使用装饰器,我们只需完成一次工作,并且将通过装饰器附加的每个方法来支持更改。

假设我们想要创建一个装饰器来记录给定方法已被弃用:

class Card {
  constructor(public suit: Suit, public rank: Rank) {
    this.suit = suit;
    this.rank = rank;
  }

  get name(): CardName {
    return `${this.rank} of ${this.suit}`;
  }

  @deprecated //  This is a decorator!
  getValue(): number {
    if (this.rank === 'Ace') return 14;
    if (this.rank === 'King') return 13;
    if (this.rank === 'Queen') return 12;
    if (this.rank === 'Jack') return 11;
    return this.rank;
  }

  // The new way to do it!
  get value(): number {
    if (this.rank === 'Ace') return 14;
    if (this.rank === 'King') return 13;
    if (this.rank === 'Queen') return 12;
    if (this.rank === 'Jack') return 11;
    return this.rank;
  }
}

const card = new Card('Spades', 'Queen');
card.getValue();

card.getValue()我们希望每当调用时都会将警告消息记录到控制台。我们可以按如下方式实现上面的装饰器:

const deprecated = <This, Arguments extends any[], ReturnValue>(
  target: (this: This, ...args: Arguments) => ReturnValue,
  context: ClassMethodDecoratorContext<
    This,
    (this: This, ...args: Arguments) => ReturnValue
  >,
) => {
  const methodName = String(context.name);

  function replacementMethod(this: This, ...args: Arguments): ReturnValue {
    console.warn(`Warning: '${methodName}' is deprecated.`);
    return target.call(this, ...args);
  }

  return replacementMethod;
};

乍一看这可能有点令人困惑,但让我们来分解一下:

  • 我们的装饰器函数有两个参数:targetcontext

  • target是我们正在装饰的方法本身。

  • context是有关该方法的元数据。

  • 我们返回一些具有相同签名的方法。

  • 在本例中,我们调用console.warn以记录弃用通知,然后调用该方法。

ClassMethodDecorator类型具有以下属性:

  • kind:装饰属性的类型。在上面的示例中,这将是method,因为我们正在 a 实例上修饰一个方法Card

  • name: 财产名称。在上面的例子中,这是getValue.

  • static:指示类元素是静态 ( true) 还是实例 ( false) 元素的值。

  • private:指示类元素是否具有私有名称的值。

  • access:可用于在运行时访问类元素的当前值的对象。

  • has:确定对象是否具有与装饰元素同名的属性。

  • get:调用所提供对象上的 setter。

装饰器提供了方便的语法糖来添加日志消息(就像我们在上面的示例中所做的那样)以及许多其他常见用例。例如,我们可以创建一个装饰器,自动将方法绑定到当前实例,或者修改方法或类的属性描述符。


您的支持是我们创作的动力!
温馨提示:本文作者系 ,经Web前端之家编辑修改或补充,转载请注明出处和本文链接:
https://jiangweishan.com/article/typescript21230231007.html

网友评论文明上网理性发言 已有0人参与

发表评论: