TypeScript 如何做装饰器

上班摸鱼时,你有没有过这样的经历:写了几十行代码,突然发现要给某个函数加个“额外功能”——比如自动记录调用时间、报错时发个提醒,要是直接改函数内部代码,不仅乱糟糟,万一改坏了还得重新调试。

其实JavaScript里藏着个好用的小工具,但它自带的能力有限,而TypeScript的装饰器刚好能帮你解决这个麻烦。它就像给你的代码“贴便利贴”,不用拆改原有的功能,就能给类、方法、属性这些代码元素加额外能力,而且TypeScript的装饰器还能做类型检查,比普通JS用着更稳。

TypeScript 如何做装饰器

先搞懂:装饰器到底是啥?

换个生活化的说法吧。假设你要开一家奶茶店,原本的流程是“做奶茶→打包给顾客”,但你想加个“给杯子印logo”的步骤,总不能把原本的做奶茶流程全改了吧?这时候的“印logo”就是个装饰——不影响原本的核心流程,只是在现有步骤上额外加东西。

TypeScript的装饰器也是这个道理:它是一种特殊的语法,能附加在类、方法、属性、参数这些代码结构上,给它们“加buff”,而且不会改动原有代码的逻辑,后期要去掉也很方便。

要注意的是,用它之前得先开个小开关:在tsconfig.json里把experimentalDecorators设为true,不然TypeScript会不认这个语法哦。

最常用的:类装饰器,给整个类加“统一能力”

如果说奶茶店要给所有杯子印logo,那对应的就是类装饰器——它作用在整个类上。举个例子,你做了个用户信息类User,想给它加个功能:实例创建时自动打个“创建日志”,不用每次手动写。

代码大概是这样的:

`typescript

// 定义一个类装饰器

function logClass(target: any) {

console.log(类 ${target.name} 被创建了);

}

// 把装饰器贴在类上

@logClass

class User {

constructor(public name: string) {}

}

// 实例化类时,就会自动打印“类 User 被创建了”

const user = new User("小明");

`

这里的target就是被装饰的类本身,相当于装饰器拿到了类的“操作权”,能在类创建时加日志、改属性,甚至继承新的能力。

灵活加功能:方法装饰器,给单个方法“贴便利贴”

要是只想给某个方法加功能,比如给用户类的sayHi方法加个“调用时计时”的功能,不用所有方法都加,这时候就用方法装饰器。

还是用奶茶店的例子:要是只给大杯奶茶加“套隔热袋”的步骤,对应的就是方法装饰器,它只作用在你指定的那个方法上。代码大概是:

`typescript

function timer(target: any, methodName: string, descriptor: PropertyDescriptor) {

// 保存原本的方法

const originalMethod = descriptor.value;

// 替换成带计时的新方法

descriptor.value = function (...args: any[]) {

const start = Date.now();

const result = originalMethod.apply(this, args);

const end = Date.now();

console.log(方法 ${methodName} 耗时 ${end - start}ms);

return result;

};

return descriptor;

}

class User {

name: string;

constructor(name: string) {

this.name = name;

}

// 把计时装饰器贴在sayHi方法上

@timer

sayHi() {

// 模拟一点耗时操作,比如查用户信息

for (let i = 0; i < 1000000; i++) {}

return 你好,我是${this.name};

}

}

const user = new User("小红");

user.sayHi(); // 会打印sayHi方法的耗时

`

这里的target是类的原型,methodName是方法名,descriptor存了方法的原始逻辑,我们可以改descriptor.value来替换方法的行为,就像给方法套了层“计时壳”。

别踩的小坑

很多新手容易忘开experimentalDecorators这个配置,导致TypeScript直接报错;另外装饰器的执行顺序要注意:参数装饰器>方法装饰器>属性装饰器>类装饰器,顺序错了可能会出奇怪的bug。

其实TypeScript装饰器就是帮你把“零散的额外功能”从原代码里抽出来,让代码更整洁、好维护。下次给代码加日志、权限校验这些功能时,试试用它,不用再把原代码改得乱糟糟啦。

上一篇 JavaScript 函数怎么定义