reflect-metadata 补上这块:开启 reflect-metadata 补上这块:开启 reflect-metadata 补上这块:开启
TypeScript 词条目录
前端Wiki/TypeScript/深入/装饰器与元数据

reflect-metadata 与类型元信息

装饰器本身拿不到 TS 的类型信息(类型早已擦除)。reflect-metadata 补上这块:开启 emitDecoratorMetadata 后,编译器把参数类型、返回类型藏进元数据,NestJS 的依赖注入就是这么知道要注入什么服务的。

操作元数据的 API:Reflect.defineMetadata 存、Reflect.getMetadata 取。虽然进不了标准,但整个 NestJS 生态都建立在它之上,React/Vue 的 TS 项目里一般用不到。

  • reflect-metadata:把类型信息存进运行时元数据
  • 需 tsconfig 同时开启 experimentalDecorators 与 emitDecoratorMetadata
  • NestJS 依赖注入的核心机制:构造器参数类型自动注入
TS
import 'reflect-metadata';

const REQUIRED = Symbol('required');

// 自定义元数据标记:某属性必填
function required(target: any, key: string) {
  Reflect.defineMetadata(REQUIRED, true, target, key);
}

class Form {
  @required
  username: string = '';

  check() {
    // 运行时读回元数据(浏览器需先 import reflect-metadata)
    const need = Reflect.getMetadata(REQUIRED, this, 'username');
    console.log('username 必填:', !!need);
  }
}
new Form().check();   // username 必填: true
JS
// 浏览器里跑这段需要先加载 reflect-metadata(如 CDN 引入)
// 这里演示等价的手工模拟,说明"元数据就是挂在对象上的隐藏信息"
const REQUIRED = Symbol('required');
function required(target, key) {
  Reflect.defineMetadata(REQUIRED, true, target, key);
}
class Form {
  constructor() { this.username = ''; }
  check() {
    const need = Reflect.getMetadata(REQUIRED, this, 'username');
    console.log('username 必填:', !!need);
  }
}
required(Form.prototype, 'username');
new Form().check();    // username 必填: true
本节要点reflect-metadata 把类型信息变成运行时元数据,是 NestJS 依赖注入的地基。