TypeScript 装饰器基础指南
目录
基本语法
启用装饰器
// tsconfig.json
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
基本结构
// 简单装饰器
function simpleDecorator(target: any) {
// 装饰器逻辑
}
@simpleDecorator
class Example {
// 类的内容
}
装饰器类型
1. 类装饰器
function Logger(constructor: Function) {
console.log('Class decorated:', constructor.name);
}
@Logger
class Person {
name = 'Max';
}
2. 方法装饰器
function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey} with:`, args);
return original.apply(this, args);
};
}
class Calculator {
@Log
add(a: number, b: number) {
return a + b;
}
}
3. 属性装饰器
function ReadOnly(target: any, propertyKey: string) {
Object.defineProperty(target, propertyKey, {
writable: false
});
}
class User {
@ReadOnly
name: string = "John";
}
装饰器工厂
装饰器工厂是返回装饰器的函数,允许自定义装饰器行为。
function Logger(prefix: string) {
return function(target: any) {
console.log(`${prefix}: ${target.name}`);
};
}
@Logger('LOGGING')
class Person {
name = 'Max';
}
返回值处理
1. 类装饰器返回值
function WithTemplate(template: string) {
return function<T extends { new(...args: any[]): {} }>(target: T) {
// 返回新的构造函数
return class extends target {
constructor(...args: any[]) {
super(...args);
console.log(template);
}
};
};
}
@WithTemplate('<h1>My Person Object</h1>')
class Person {
name = 'Max';
}
2. 方法装饰器返回值
function Measure(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
const start = performance.now();
const result = originalMethod.apply(this, args);
const end = performance.now();
console.log(`${propertyKey} took ${end - start}ms`);
return result;
};
return descriptor;
}
应用示例
1. 验证装饰器
function Validate(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(price: number) {
if (price <= 0) {
throw new Error('Price must be positive');
}
return originalMethod.call(this, price);
};
}
class Product {
@Validate
setPrice(price: number) {
this._price = price;
}
}
2. 替换类实现
function APIVersion(version: string) {
return function<T extends { new(...args: any[]): {} }>(originalConstructor: T) {
return class extends originalConstructor {
constructor(...args: any[]) {
super(...args);
this.version = version;
}
getVersion() {
return this.version;
}
};
};
}
@APIVersion('1.0.0')
class API {
// 原始类实现
}
const api = new API();
console.log(api.getVersion()); // 输出: 1.0.0
3. 属性转换
function UpperCase(target: any, propertyKey: string) {
let value: string;
Object.defineProperty(target, propertyKey, {
get: () => value,
set: (newValue: string) => {
value = newValue.toUpperCase();
}
});
}
class User {
@UpperCase
name: string;
}
const user = new User();
user.name = 'john';
console.log(user.name); // 输出: JOHN