reflect-metadata 与 TypeScript:完整指南与实战示例
欢迎阅读这份关于 reflect-metadata 库的 TypeScript 完整指南。该库是现代框架(如 Angular、NestJS 和 TypeORM)的基石。它允许你在运行时为类、方法、属性和参数添加和读取元数据(关于数据的数据)。如果你想理解 TypeScript 中装饰器和依赖注入(Dependency Injection, DI)的工作原理,那么掌握 reflect-metadata 是必不可少的一步。
1. 什么是 reflect-metadata?为什么需要它?
reflect-metadata 是内置对象 Reflect 的一个 polyfill(实现),后者是 ES2016(ES7)规范的一部分。该库的主要目的是提供一个 API,用于操作与代码元素(类、方法、属性)关联的元数据。标准 JavaScript 中缺少此功能,因此 TypeScript 需要单独安装这个包。
为什么需要它?假设你正在编写一个框架。你需要知道一个类需要哪些依赖项,哪些路由(routes)绑定到了控制器的方法上,或者实体的哪些字段需要序列化为 JSON。如果没有元数据,你只能将这些信息存储在单独的配置文件中,或者使用复杂的模式。而 reflect-metadata 允许你将信息直接存储在代码中,使代码更具自文档性,也更易于分析。
该库与装饰器紧密相关。装饰器是一个应用于类、方法或属性的函数。在装饰器内部,你可以调用 Reflect.defineMetadata 来保存某些信息,然后在程序的其他地方使用 Reflect.getMetadata 来获取它。这是实现依赖注入、ORM(对象关系映射)、验证以及许多其他模式的基础。
2. 安装步骤
通过 npm(Node 包管理器)安装该库。请确保你已经安装了 Node.js(版本 12 或更高)。
npm install reflect-metadata --save
安装完成后,需要在入口文件(通常是 main.ts 或 index.ts)的最开始导入该库,使其全局可用。
import "reflect-metadata";
重要提示: 导入必须在任何使用 Reflect 的代码之前执行。如果你使用框架(例如 Angular),它会自动为你完成此操作。否则,请将此行添加到文件开头。
此外,还需要在 tsconfig.json 文件中启用装饰器和元数据支持:
{
"compilerOptions": {
"target": "ES6",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
emitDecoratorMetadata 标志会强制 TypeScript 编译器为被装饰的元素生成类型元数据。这对于许多框架的正常运行是必需的。
3. 快速上手——最小工作示例
让我们创建一个简单的示例,演示如何向类添加元数据并读取它。
import "reflect-metadata";
// 1. 定义元数据的键
const METADATA_KEY = "my_custom_key";
// 2. 创建一个添加元数据的装饰器
function MyDecorator(value: string) {
return function (target: any) {
// target 是类的构造函数
Reflect.defineMetadata(METADATA_KEY, value, target);
};
}
// 3. 将装饰器应用于类
@MyDecorator("这是我的类")
class MyClass {
greet() {
console.l