TypeScript 装饰器与反射元数据实战指南

作者:代码拾荒

时间:2026-11-01

浏览:599

本文详细解析 TypeScript 装饰器的五种类型及其工作原理,涵盖类、方法、属性等场景。通过实例演示如何结合 reflect-metadata 实现元数据反射,并给出 tsconfig.json 中开启实验性装饰器的具体配置步骤,帮助开发者在编译时捕获错误并增强代码行为。

文章目录

介绍

近年来,JavaScript 及其生态系统经历了快速迭代,TypeScript 因此成为众多开发者的首选语言。其核心优势在于静态类型系统,能够在编译阶段而非运行阶段捕获潜在错误。此外,TypeScript 不仅兼容 ES6+ 特性,还引入了枚举、命名空间以及装饰器等独有功能。

装饰器简介

在 TypeScript 中,装饰器是一种特殊的声明形式,可附加至类声明、方法、属性、访问器或参数之上。其核心目的在于增强现有类、方法或属性的行为,或为其添加新功能。借助装饰器,我们无需修改原始类的定义,即可为类扩展新的特性。

在 TypeScript 中,装饰器采用 @expression 的语法形式。其中,expression 必须是一个返回函数的表达式,该函数将在运行时被调用,并接收相关的装饰器参数。

TypeScript 支持以下几种类型的装饰器:

  • 类装饰器
  • 方法装饰器
  • 访问器装饰器
  • 属性装饰器
  • 参数装饰器

类装饰器

类装饰器作用于类的构造函数,用于观察、修改或替换类的定义。应用时,它作为函数被调用,并将构造函数作为唯一参数传入。

function Sealed(constructor: Function) {
    Object.seal(constructor);
    Object.seal(constructor.prototype);
}
@Sealed
class Greeter {
    constructor(public greeting: string) {}
    greet() {
        return "Hello, " + this.greeting;
    }
}

方法装饰器

方法装饰器作用于方法的属性描述符,可用于观察、修改或替换方法定义。当装饰器执行时,它会接收三个参数:当前类的原型、方法名以及该方法的属性描述符。

function Log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
    let originalMethod = descriptor.value; // 保存原始函数
    descriptor.value = function (...args: any[]) {
        console.log("Arguments: ", JSON.stringify(args));
        let result = originalMethod.apply(this, args);
 console.log("Result: ", result);
        return result;
    }
}
class Calculator {
    @Log
    add(x: number, y: number): number {
        return x + y;
    }
}

访问器装饰器

访问器装饰器作用于访问器的属性描述符,可用于观察、修改或替换访问器定义。其语法结构与装饰器类似。

function ReadOnly(target: any, key: string, descriptor: PropertyDescriptor) {
    descriptor.writable = false;
    return descriptor;
}
class Circle {
    private _radius: number;
    constructor(radius: number) {
        this._radius = radius;
    }
    @ReadOnly
    get radius() {
        return this._radius;
    }
}

装饰器与反射元数据

为了使装饰器更高效地工作,TypeScript 提供了反射元数据 API。这是一个实验性 API,允许装饰器在声明时添加元数据。可通过 npm 安装反射元数据 API:

反射元数据(Reflect Metadata)是一个实验性的 API,用于在声明装饰器时执行元数据类型注解和元数据反射。

npm install reflect-metadata --save

随后,你需要在全局范围内导入反射 API:

import "reflect-metadata";

在 TypeScript 配置文件 tsconfig.json 中,你需要开启 emitDecoratorMetadata 选项:

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "ES5",
    "module": "commonjs"
  }
}

配置完成后,即可在装饰器中使用反射 API:

function logType(target : any, key : string) {
  var t = Reflect.getMetadata("design:type", target, key);
  console.log(`${key} type: ${t.name}`);
}
class Demo{ 
  @logType
  public attr1 : string;
}

以上介绍了装饰器的基本原理与应用。装饰器能使代码更简洁、易读,并提升代码的可管理性和可维护性。但需注意,装饰器目前仍处于实验阶段,若在生产环境中使用,需充分了解可能带来的风险。

结论

TypeScript 的装饰器为我们提供了一种强大的工具,可在运行时改变类的行为。深入理解装饰器的工作原理,有助于构建更强大、灵活且易于维护的应用程序。

到此这篇关于TypeScript装饰器与反射元数据的文章就介绍到这了,更多相关TypeScript装饰器与反射元数据内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章