当前位置: 首页 > ops >正文

reflect-metadata作用

详细讲解 reflect-metadata 的作用、用法,并配合多个实用例子,尤其是它如何结合 TypeScript 装饰器来实现高级功能,比如依赖注入、类型推断、字段注解等。


🧠 一、reflect-metadata 是什么?

reflect-metadata 是一个支持 元编程(Meta Programming) 的库,它允许你给类、属性、方法、函数参数添加“元信息”并在运行时读取这些信息。
大白话:类似于中间件,什么路由中间件啥的,写好后加在那个方法上就能去操作那个方法的或者类啥的能力,比如写个日志打印,添加到的函数都会被打印日志,比如路由中间件本身也是有种元编程能力,加上就能在加上的路由上都执行中间件,或者Refet,可以操作所有对象的属性方法啥的,proxy,被proxy代理的变量都会被监控getset等等,总之就是可以搞其他写好的程序的程序就喊具有元编程能力的程序

🎯 二、应用场景

应用描述
🧱 类型系统扩展读取类、方法、参数的类型
📦 依赖注入框架自动注入构造函数参数的实例
📊 表单/数据校验读取字段类型与校验规则
🧩 ORM 映射标注类字段 → 数据库字段
🌐 路由控制器使用装饰器定义路由、方法等

✅ 三、启用 reflect-metadata 前提

  1. 安装:
npm install reflect-metadata
  1. 在入口文件(如 main.ts)顶部引入:
import 'reflect-metadata'
  1. tsconfig.json 配置:
{"experimentalDecorators": true,"emitDecoratorMetadata": true
}

🚀 四、核心 API 用法示例

✅ 1. 属性元数据(使用装饰器 + metadata)

import 'reflect-metadata'function Label(label: string) {return Reflect.metadata('label', label)
}class User {@Label('用户名')name: string
}// 获取 name 字段的自定义元信息
const label = Reflect.getMetadata('label', User.prototype, 'name')
console.log(label) // 输出:用户名

✅ 2. 读取属性的类型信息(需要 emitDecoratorMetadata)

import 'reflect-metadata'class User {name: stringage: number
}const type1 = Reflect.getMetadata('design:type', User.prototype, 'name')
const type2 = Reflect.getMetadata('design:type', User.prototype, 'age')console.log(type1.name) // String
console.log(type2.name) // Number
  • 这是 TypeScript 编译器自动生成的类型信息。
  • design:type 是 reflect-metadata 保留的 key。

✅ 3. 读取方法参数类型(用于依赖注入)

import 'reflect-metadata'class LoggerService {}
class UserService {}class App {constructor(public logger: LoggerService, public userService: UserService) {}
}const paramTypes = Reflect.getMetadata('design:paramtypes', App)
console.log(paramTypes.map((t: any) => t.name)) // ['LoggerService', 'UserService']
  • 在依赖注入框架中,框架就能根据这些类型自动创建和注入实例。

✅ 4. 自定义字段验证装饰器

import 'reflect-metadata'function Required(target: any, key: string) {Reflect.defineMetadata('required', true, target, key)
}function isFieldRequired(target: any, key: string) {return Reflect.getMetadata('required', target, key)
}class Product {@Requiredname: stringprice: number
}console.log(isFieldRequired(Product.prototype, 'name')) // true
console.log(isFieldRequired(Product.prototype, 'price')) // undefined

🌍 五、结合场景示例:构建简易依赖注入容器

import 'reflect-metadata'class Logger {log(msg: string) {console.log('Log:', msg)}
}class Service {constructor(public logger: Logger) {}
}// 简易 DI 容器
function create<T>(target: new (...args: any[]) => T): T {const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []const params = paramTypes.map((type: any) => new type())return new target(...params)
}const service = create(Service)
service.logger.log('Hello DI') // 输出:Log: Hello DI

🎯 利用 design:paramtypes 读取构造函数参数类型,并自动创建依赖项实例。


⚠️ 六、注意事项

限制描述
类型信息只在 TS 编译时生成必须开启 emitDecoratorMetadata
必须引入 reflect-metadata否则 Reflect API 不可用
运行时类型是构造函数例如 StringNumber,不是具体值类型

🧾 七、常用内置 Metadata Key

Key描述
design:type属性的类型
design:paramtypes构造函数或方法的参数类型数组
design:returntype方法的返回类型

✅ 总结

内容
📦 工具reflect-metadata 提供在运行时定义/获取元信息的能力
🔧 搭配常与装饰器、TypeScript 一起使用
💡 应用依赖注入、类型反射、表单校验、ORM 等场景广泛使用
📌 核心 APIReflect.defineMetadata()Reflect.getMetadata()design:type
🚀 必备配置experimentalDecorators: true + emitDecoratorMetadata: true

http://www.xdnf.cn/news/9022.html

相关文章:

  • Ubuntu | NVIDIA 驱动、CUDA 与 cuDNN 的安装与配置 / 常见问题及解决方法
  • Zabbix集成Grfana自定义仪表盘
  • World of Warcraft [CLASSIC] Jewelcrafting Gemstone 3 [80 WLK]
  • 初等数论--Garner‘s 算法
  • 邻近标记技术(PL):探索生物分子相互作用的前沿工具
  • Java设计模式之适配器模式
  • AI时代新词-多模态(Multimodal)
  • 测评机构如何通过漏扫保障软件安全?扫描范围与局限解析
  • leetcode:2235. 两整数相加(python3解法,数学相关算法题)
  • 十六进制字符转十进制算法
  • C++——STL——unordered_map与unordered_set的使用以及使用哈希表封装unordered_map/set
  • https的进化之路(八卦版)
  • JVM 深度解析
  • k-way Hypergraph Partitioning via n-Level Recursive Bisection【2016 ALENEX】文献总结
  • N2语法 时间
  • 协同过滤实现电影推荐
  • 931. 用三种不同颜色为网格涂色
  • 力扣刷题(第三十八天)
  • Rk3568驱动开发_设备树点亮LED_11
  • 系统分析师备考总结
  • SPL做量化—-VMA(变异平均线)
  • node.js配置变量
  • 内容的逐次呈现以及二分查找(算法)
  • DeepSORT中的卡尔曼滤波可观测性分析:从原理到实践
  • 提示词写的好,用VSCODE+python+Claude3.5开发edge扩展插件(2)
  • 内网映射有什么作用,如何实现内网的网络地址映射到公网连接?
  • 【东枫科技】基于Docker,Nodejs,GitSite构建一个KB站点
  • 电路中常见器件作用(二极管 三极管 MOS)
  • OpenCV (C/C++) 实现 Scharr 算子进行边缘检测
  • MySQL组合索引优化策略