TypeScript 5 装饰器实战:从实验性语法到 ECMAScript 标准
Sarah Wong | 2026-08-26T23:00:23 | JavaScript
TypeScript 5 正式支持了 ECMAScript 标准装饰器,本文对比新旧装饰器差异,并演示日志、权限校验等实用装饰器实现。
# TypeScript 5 装饰器实战 ## 旧装饰器 vs 新装饰器 TypeScript 5 之前的装饰器需要 `experimentalDecorators: true`,基于 2016 年的旧提案。TypeScript 5 正式支持 Stage 3 标准装饰器,无需额外配置。 ## 方法装饰器:自动日志 ```typescript function log( target: any, context: ClassMethodDecoratorContext ) { const methodName = String(context.name); return function (this: any, ...args: any[]) { console.log('[' + methodName + '] 调用参数:', args); const start = performance.now(); const result = target.apply(this, args); const elapsed = performance.now() - start; console.log('[' + methodName + '] 耗时: ' + elapsed.toFixed(2) + 'ms'); return result; }; } class UserService { @log findById(id: number) { // 模拟数据库查询 return { id: id, name: '张三' }; } } ``` ## 类装饰器:自动注册 ```typescript const registry: Map = new Map(); function register(target: any, context: ClassDecoratorContext) { const name = String(context.name); registry.set(name, target); console.log('已注册组件: ' + name); } @register class EmailService { send(to: string, body: string) { console.log('发送邮件到 ' + to); } } ``` ## 字段装饰器:参数校验 ```typescript function min(minValue: number) { return function (target: undefined, context: ClassFieldDecoratorContext) { return function (initialValue: number) { if (initialValue < minValue) { throw new Error(String(context.name) + ' 不能小于 ' + minValue); } return initialValue; }; }; } class Config { @min(1) maxRetries = 3; @min(1000) timeout = 5000; } ``` ## 迁移建议 1. 新项目直接使用标准装饰器 2. 旧项目可以保持 `experimentalDecorators`,后续逐步迁移 3. NestJS、TypeORM 等框架仍使用旧装饰器,迁移需等框架支持