返回
揭秘 TypeScript 装饰器的强大功能
前端
2023-12-21 23:21:00
TypeScript 装饰器的全景
JavaScript 的装饰器还在提案阶段,但 TypeScript 已经基于该提案实现了自己的装饰器特性。装饰器模式是一种强大的元编程技术,它允许您在编译时修改代码的行为。
在 TypeScript 中,装饰器有四种类型:
- 类装饰器
- 方法装饰器
- 参数装饰器
- 属性装饰器
类装饰器
类装饰器用于修改类的行为。它接受一个类作为参数,并返回一个修改后的类。例如,以下装饰器将类标记为不可实例化:
function nonInstantiable(target: Function) {
target.prototype.constructor = null;
}
@nonInstantiable
class MyClass {}
方法装饰器
方法装饰器用于修改方法的行为。它接受一个方法作为参数,并返回一个修改后的方法。例如,以下装饰器在方法调用前后记录日志:
function log(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${propertyKey} with arguments:`, args);
const result = originalMethod.apply(this, args);
console.log(`Method ${propertyKey} returned:`, result);
return result;
};
}
class MyClass {
@log
greet(name: string) {
console.log(`Hello, ${name}!`);
}
}
参数装饰器
参数装饰器用于修改方法参数的行为。它接受一个方法参数作为参数,并返回一个修改后的参数。例如,以下装饰器验证参数是否为非空:
function nonNull(target: Object, propertyKey: string | symbol, parameterIndex: number) {
const originalMethod = target[propertyKey] as Function;
target[propertyKey] = function (...args: any[]) {
if (args[parameterIndex] === null) {
throw new Error(`Argument ${parameterIndex} cannot be null`);
}
return originalMethod.apply(this, args);
};
}
class MyClass {
greet(@nonNull name: string) {
console.log(`Hello, ${name}!`);
}
}
属性装饰器
属性装饰器用于修改属性的行为。它接受一个属性作为参数,并返回一个修改后的属性。例如,以下装饰器为属性添加验证逻辑:
function validate(target: Object, propertyKey: string | symbol) {
const originalGetter = Object.getOwnPropertyDescriptor(target, propertyKey)?.get;
Object.defineProperty(target, propertyKey, {
get: function () {
const value = originalGetter?.call(this);
if (value === undefined) {
throw new Error(`Property ${propertyKey} cannot be undefined`);
}
return value;
},
});
}
class MyClass {
@validate
name: string | undefined;
}
总结
TypeScript 中的装饰器是一种强大的工具,它允许您在编译时增强代码的行为。通过理解不同类型的装饰器,您可以利用它们的优势来提高代码的可维护性、灵活性