首页 前端知识 【TS系列】TypeScript进阶(五)

【TS系列】TypeScript进阶(五)

2024-08-30 20:08:09 前端知识 前端哥 242 358 我要收藏

走进TypeScript

  • 章节回顾:
  • 【TS系列】初识TypeScript
  • 【TS系列】TypeScript之基本类型
  • 【TS系列】TypeScript进阶(一)
  • 【TS系列】TypeScript进阶(二)
  • 【TS系列】TypeScript进阶(三)
  • 【TS系列】TypeScript进阶(四)
    • 一、TypeScript 装饰器
      • 1. 装饰器是什么
      • 2. 装饰器的分类
      • 3. 类装饰器
      • 4. 属性装饰器
      • 5. 方法装饰器
      • 6. 参数装饰器
  • 小结

章节回顾:

【TS系列】初识TypeScript

【TS系列】TypeScript之基本类型

【TS系列】TypeScript进阶(一)

【TS系列】TypeScript进阶(二)

【TS系列】TypeScript进阶(三)

【TS系列】TypeScript进阶(四)

如果文章有什么需要改进的地方还请大佬不吝赐教👏👏
在此先感谢各位大佬啦~~🤞🤞
在这里插入图片描述

一、TypeScript 装饰器

1. 装饰器是什么

  • 它是一个表达式
  • 该表达式被执行后,返回一个函数
  • 函数的入参分别为 target、name 和 descriptor
  • 执行该函数后,可能返回 descriptor 对象,用于配置 target 对象

2. 装饰器的分类

  • 类装饰器(Class decorators)
  • 属性装饰器(Property decorators)
  • 方法装饰器(Method decorators)
  • 参数装饰器(Parameter decorators)

3. 类装饰器

类装饰器声明:

declare type ClassDecorator = <TFunction extends Function>(
  target: TFunction
) => TFunction | void;

类装饰器顾名思义,就是用来装饰类的。它接收一个参数:

  • target: TFunction - 被装饰的类

例子:

function Greeter(target: Function): void {
  target.prototype.greet = function (): void {
    console.log("Hello Semlinker!");
  };
}

@Greeter
class Greeting {
  constructor() {
    // 内部实现
  }
}

let myGreeting = new Greeting();
myGreeting.greet(); // console output: 'Hello Semlinker!';

上面的例子中,我们定义了 Greeter 类装饰器,同时我们使用了 @Greeter 语法糖,来使用装饰器。

具体实现如下:

function Greeter(greeting: string) {
  return function (target: Function) {
    target.prototype.greet = function (): void {
      console.log(greeting);
    };
  };
}

@Greeter("Hello TS!")
class Greeting {
  constructor() {
    // 内部实现
  }
}

let myGreeting = new Greeting();
myGreeting.greet(); // console output: 'Hello TS!';

4. 属性装饰器

属性装饰器声明:

declare type PropertyDecorator = (target:Object, 
  propertyKey: string | symbol ) => void;

属性装饰器顾名思义,用来装饰类的属性。它接收两个参数:

  • target: Object - 被装饰的类
  • propertyKey: string | symbol - 被装饰类的属性名

趁热打铁,马上来个例子热热身:

function logProperty(target: any, key: string) {
  delete target[key];

  const backingField = "_" + key;

  Object.defineProperty(target, backingField, {
    writable: true,
    enumerable: true,
    configurable: true
  });

  // property getter
  const getter = function (this: any) {
    const currVal = this[backingField];
    console.log(`Get: ${key} => ${currVal}`);
    return currVal;
  };

  // property setter
  const setter = function (this: any, newVal: any) {
    console.log(`Set: ${key} => ${newVal}`);
    this[backingField] = newVal;
  };

  // Create new property with getter and setter
  Object.defineProperty(target, key, {
    get: getter,
    set: setter,
    enumerable: true,
    configurable: true
  });
}

class Person { 
  @logProperty
  public name: string;

  constructor(name : string) { 
    this.name = name;
  }
}

const p1 = new Person("semlinker");
p1.name = "kakuqo";

以上代码我们定义了一个 logProperty 函数,来跟踪用户对属性的操作,当代码成功运行后,在控制台会输出以下结果:

Set: name => semlinker
Set: name => kakuqo

5. 方法装饰器

方法装饰器声明:

declare type MethodDecorator = <T>(target:Object, propertyKey: string | symbol,          
  descriptor: TypePropertyDescript<T>) => TypedPropertyDescriptor<T> | void;

方法装饰器顾名思义,用来装饰类的方法。它接收三个参数:

  • target: Object - 被装饰的类
  • propertyKey: string | symbol - 方法名
  • descriptor: TypePropertyDescript - 属性描述符

废话不多说,直接上例子:

function LogOutput(tarage: Function, key: string, descriptor: any) {
  let originalMethod = descriptor.value;
  let newMethod = function(...args: any[]): any {
    let result: any = originalMethod.apply(this, args);
    if(!this.loggedOutput) {
      this.loggedOutput = new Array<any>();
    }
    this.loggedOutput.push({
      method: key,
      parameters: args,
      output: result,
      timestamp: new Date()
    });
    return result;
  };
  descriptor.value = newMethod;
}

class Calculator {
  @LogOutput
  double (num: number): number {
    return num * 2;
  }
}

let calc = new Calculator();
calc.double(11);
// console ouput: [{method: "double", output: 22, ...}]
console.log(calc.loggedOutput); 

下面我们来介绍一下参数装饰器。

6. 参数装饰器

参数装饰器声明:

declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, 
  parameterIndex: number ) => void

参数装饰器顾名思义,是用来装饰函数参数,它接收三个参数:

  • target: Object - 被装饰的类
  • propertyKey: string | symbol - 方法名
  • parameterIndex: number - 方法中参数的索引值
function Log(target: Function, key: string, parameterIndex: number) {
  let functionLogged = key || target.prototype.constructor.name;
  console.log(`The parameter in position ${parameterIndex} at ${functionLogged} has
    been decorated`);
}

class Greeter {
  greeting: string;
  constructor(@Log phrase: string) {
    this.greeting = phrase; 
  }
}

// console output: The parameter in position 0 
// at Greeter has been decorated

小结

以上就是关于TypeScript的进阶内容介绍,根据一些参考资料作出总结,如果侵权,请联系删除!!谢谢!
后续将会围绕TypeScript相关内容及其知识点不定期持续更新,感谢一路有你们的关注和陪伴!
(若有错误,请批评改正,谢谢~)

转载请注明出处或者链接地址:https://www.qianduange.cn//article/17244.html
标签
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!