TypeScript enum 和 const enum 有什么区别?装饰器的用途是什么?
请说明 TypeScript 中 enum(枚举)的运行机制,const enum 与普通 enum 的区别,以及装饰器的常见用途。
回答
Yahuda
枚举(enum):
enum Direction {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT'
}
// 使用
const dir: Direction = Direction.Up;
普通 enum vs const enum:
| 特性 | enum | const enum |
|---|---|---|
| 编译产物 | 生成 JS 对象(运行时存在) | 不生成代码,成员值内联 |
| 性能 | 有运行时查找开销 | 零开销(直接替换为值) |
| 反向映射 | ✅ 支持 Direction['UP'] | ❌ 不支持 |
| 使用限制 | 无 | 不能用在 ambient context |
// enum Direction { Up = 'UP' } 编译为:
var Direction;
(function (Direction) {
Direction["Up"] = "UP";
})(Direction || (Direction = {}));
// const enum Direction { Up = 'UP' } 编译后:
// 无代码,直接用 Direction.Up → 'UP'
装饰器(Decorator):
// 类装饰器
function LogClass(target: Function) {
console.log(`类: ${target.name}`);
}
@LogClass
class MyClass {}
// 方法装饰器
function LogMethod(target: any, key: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`调用 ${key},参数:`, args);
return original.apply(this, args);
};
}
常见装饰器用途:
- Angular:
@Component、@Injectable、@Input、@Output - NestJS:
@Module、@Controller、@Get()、@Injectable() - TypeORM:
@Entity、@Column、@ManyToOne - 验证:
@IsEmail()、@Min(0)(class-validator)
注意:装饰器是实验特性(experimentalDecorators: true),ES 标准的装饰器提案语法不同。