@decorator 装饰器

最后更新:2026-10-22

@decorator 装饰器

装饰器是加在类、方法、属性、参数前的特殊语法 @name:用一层函数包装给类附加行为(日志、校验、依赖注入),不用改动类本身的代码。TS 里装饰器仍是实验性特性,需要 tsconfig 开启 experimentalDecorators;NestJS、TypeORM 等框架大量使用,是读懂这类框架源码的必修课。

分组工程与实战
类型语法
严格模式不需要

ℹ️ 说明 编辑器将 TypeScript 转译为 JavaScript 后运行(不做类型检查);类型检查结果见示例 Output。

📝 语法

// 类装饰器:接收构造函数
function sealed(Ctor: Function): void {
  Object.seal(Ctor);
  Object.seal(Ctor.prototype);
}

// 方法装饰器:接收 (原型, 方法名, 属性描述符)
function logged(target: object, key: string, desc: PropertyDescriptor): void {
  const original = desc.value;
  desc.value = function (...args: unknown[]) {
    console.log("call", key, args);
    return original.apply(this, args);
  };
}

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

⚙️ 参数

ClassDecorator参数是类构造函数;可修改类、返回新类替换原类,@sealed 这类"整体约束"常用它
MethodDecorator在类定义时执行一次,通过改写 desc.value 包装原方法;返回新描述符可整体替换
experimentalDecoratorstsconfig 开关,不加会报"装饰器是实验特性"错误;框架生态(NestJS 等)当前普遍基于此版本

返回值:类装饰器可返回一个新构造函数替换原类(不返回则沿用原类);方法装饰器可返回新的属性描述符,或返回 undefined 仅通过副作用修改。

▶ 示例

修改下面的代码,点击试一试查看转译运行结果:

输出:

-> add(2, 3)
add = 5
-> mul(4, 5)
mul = 20

(转译后运行输出;方法装饰器在类定义时就完成包装——调用时先打印 -> add(2, 3) 再返回结果)

💡 要点

ℹ️ 说明 执行时机是"类定义时"而非"方法调用时":装饰器函数在 class 声明被求值时就运行一次,把 desc.value 换成包装后的版本;之后每次调用走的都是包装版。
💡 提示 需要给装饰器传参数时用"装饰器工厂":@log("debug") 是一个返回装饰器函数的函数——外层收配置,内层收 (target, key, desc)。NestJS 的 @Injectable() 带括号就是工厂。
⚠️ 注意 实验版与标准版签名不兼容:TS 5 起可以不用 experimentalDecorators 而使用 ES 标准装饰器,方法装饰器第二参数从 (target, key, desc) 变成 context 对象。阅读老项目/框架代码前先确认用的是哪一版。
更多案例即将上线。

📚 相关教程

❓ 常见问题

Q 装饰器和普通的高阶函数有什么区别?
A 本质都是"函数包函数"。区别在声明位置:装饰器写在被装饰者上方,编译器负责把它接到定义处,类/方法本体保持干净;高阶函数则要在创建处显式包一层(const add = logged(Calculator.prototype.add))。装饰器更像"贴标签",适合横切关注点。
Q NestJS 里的 @Injectable() 是怎么工作的?
A @Injectable() 是装饰器工厂,返回的类装饰器给类挂上元数据(标记它可被依赖注入容器实例化)。容器在创建 Controller 时读取构造函数参数的类型/装饰器元数据,自动解析并注入依赖——装饰器本身不做注入,只是登记信息。
Q 新项目该用实验版还是标准版装饰器?
A 看框架:跟随 NestJS/TypeORM 等生态就开 experimentalDecorators(它们目前依赖旧语义);纯自有代码推荐标准版(TS 5+ 默认),语义已进 ES 标准、不再有"实验"包袱,但两版写法不能混用。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏