新版装饰器概述
TypeScript 5.0 实现了 TC39 Stage 3 的装饰器提案,这与之前 experimentalDecorators 的语义有重要差异。
类装饰器
function sealed(target: typeof BugReport) {
Object.seal(target);
Object.seal(target.prototype);
}
@sealed
class BugReport {
type = "report";
title: string;
constructor(t: string) {
this.title = t;
}
}
方法装饰器
function loggedMethod(originalMethod: any, context: ClassMethodDecoratorContext) {
const methodName = String(context.name);
function replacementMethod(this: any, ...args: any[]) {
console.log(LOG: Entering method '${methodName}');
const result = originalMethod.call(this, ...args);
console.log(LOG: Exiting method '${methodName}');
return result;
}
return replacementMethod;
}
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
@loggedMethod
greet() {
console.log(Hello, my name is ${this.name}.);
}
}
Accessor 装饰器
新增的 accessor 关键字配合装饰器使用:
function clamp({ min, max }: { min: number; max: number }) {
return function<This, Value extends number>(
target: ClassAccessorDecoratorTarget<This, Value>,
context: ClassAccessorDecoratorContext<This, Value>
): ClassAccessorDecoratorResult<This, Value> {
return {
set(value) {
target.set.call(this, Math.min(Math.max(value, min), max) as Value);
},
};
};
}
class Temperature {
@clamp({ min: -273.15, max: Infinity })
accessor celsius: number = 0;
}
迁移注意事项
新版装饰器与旧版不兼容,迁移时需要注意:
1. 移除 experimentalDecorators: true 配置
2. 装饰器函数签名发生变化
3. 部分元数据相关 API 需要等待 decoratorMetadata 提案落地
总结
新版装饰器更符合 JavaScript 标准,类型推断更准确,是值得逐步迁移的方向。