首页 前端知识 【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

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