TypeScript 属性装饰器怎么用
在前端开发里,你有没有遇到过这种情况:写了一个用户信息类,需要在每个属性赋值时加一层校验——比如年龄不能超过120,邮箱必须带@符号?要是用普通的JavaScript,可能得在每个属性的set方法里写重复的判断,不仅麻烦还容易漏。这时候,TypeScript的属性装饰器就能帮你轻松解决这类重复工作,让代码更简洁、易维护。
属性装饰器是TypeScript提供的一种特殊语法,用来修饰类的属性,能在属性定义时添加额外的逻辑,比如校验、日志、权限控制等。它本身是一个函数,接收两个参数:第一个是属性所在的类的构造函数,第二个是属性的名字,不用记复杂的参数,用的时候直接套就行。

举个生活化的例子,假设我们要做一个用户年龄的校验装饰器,要求输入的年龄必须在0到120之间。先定义这个属性装饰器,用JavaScript的写法很简单:
function AgeValidate(target: any, propertyKey: string) {
// 这里的逻辑会在属性被赋值时触发
let value: number;
const getter = function() { return value; };
const setter = function(newVal: number) {
if (newVal < 0 || newVal > 120) {
throw new Error(年龄必须在0-120之间,你输入的是${newVal});
}
value = newVal;
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter
});
}
用的时候,直接在类的属性前加这个装饰器就行,就像给属性贴了个“校验标签”:
class User {
@AgeValidate
age: number = 0;
}
这样写后,只要给age赋值,就会自动触发校验。比如new User().age = 150,直接会报错,完全不用在类里写重复的校验代码。
可能有人会问,这个装饰器的逻辑是怎么生效的?其实核心是Object.defineProperty这个方法,它能修改属性的get和set函数——原来的属性直接赋值,现在变成了“赋值时先执行校验,再存值;取值时直接返回值”,相当于给属性套了一层“自动处理的壳”,这就是装饰器的核心原理:不修改原类的结构,只给属性加额外能力。
再讲一个实用的场景,比如给属性加日志,记录每次赋值的过程,方便调试:
function LogProperty(target: any, propertyKey: string) {
let value: any;
const getter = function() {
console.log(获取${propertyKey}:${value});
return value;
};
const setter = function(newVal: any) {
console.log(设置${propertyKey}为:${newVal});
value = newVal;
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter
});
}
用在用户名属性上:
class User {
@LogProperty
username: string = '';
}
当执行new User().username = '小明'时,控制台会自动打印“设置username为:小明”,取值时还会打印“获取username:小明”,不用手动加console.log,整洁又高效。
最后要注意,TypeScript的装饰器是实验性语法,用之前需要在tsconfig.json里开两个配置:"experimentalDecorators": true和"emitDecoratorMetadata": true,不然会报错,这一步就像给工具“解锁”功能,简单设置就能用。
总的来说,属性装饰器就是前端里的“属性外挂”,把重复的校验、日志等逻辑抽出来,用装饰器贴到需要的属性上,让代码更清爽。日常开发中,不管是做参数校验,还是埋点、权限控制,用它都能减少冗余代码,提升开发效率,尤其适合多人协作的项目,大家统一用装饰器处理通用逻辑,代码的可维护性会好很多。