You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取TypeScript类实例各属性对应的装饰器信息

实现方案

TypeScript 本身不会自动存储装饰器与属性的关联信息,你需要在实现装饰器时手动把装饰器信息写入元数据,后续遍历属性时从元数据中读取即可,需要借助reflect-metadata库完成元数据操作。

1. 前置配置

首先安装依赖:

npm install reflect-metadata

修改tsconfig.json开启装饰器相关配置:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

在项目入口文件顶部引入依赖:

import 'reflect-metadata';

2. 实现带元数据存储的装饰器

定义全局唯一的元数据key避免命名冲突,在每个装饰器触发时,把装饰器类型、参数等信息存入对应属性的元数据中:

// 元数据存储key,全局唯一
const DECORATORS_META_KEY = 'custom:property-decorators';

// @key 装饰器实现
function key(target: Object, propertyKey: string | symbol) {
  // 读取该属性已有的装饰器列表,无则初始化空数组
  const existDecos = Reflect.getMetadata(DECORATORS_META_KEY, target, propertyKey) || [];
  existDecos.push({ type: 'key' });
  // 写入元数据
  Reflect.defineMetadata(DECORATORS_META_KEY, existDecos, target, propertyKey);
}

// @maxlength 装饰器实现
function maxlength(length: number) {
  return function(target: Object, propertyKey: string | symbol) {
    const existDecos = Reflect.getMetadata(DECORATORS_META_KEY, target, propertyKey) || [];
    existDecos.push({ 
      type: 'maxlength',
      params: length 
    });
    Reflect.defineMetadata(DECORATORS_META_KEY, existDecos, target, propertyKey);
  }
}

3. 遍历属性读取装饰器信息

方式1:遍历实例属性(要求属性有初始赋值)

如果类的属性有初始值,实例化后可以直接用for...in遍历:

class User {
  @key
  id: number = 0; // 给初始值,实例化后可被遍历到

  @maxlength(50)
  Name: string = ''; // 给初始值
}

const user = new User();
for (const property in user) {
  // 从类原型上读取该属性的装饰器元数据
  const decorators = Reflect.getMetadata(DECORATORS_META_KEY, User.prototype, property);
  console.log(`属性${property}的装饰器列表:`, decorators);
  
  // 示例:判断属性是否有@key装饰器
  const hasKey = decorators?.some(item => item.type === 'key') ?? false;
  console.log(`属性${property}是否带@key装饰器:`, hasKey);
}

方式2:遍历类声明的所有属性(无需属性初始化)

如果不想给属性加初始值,可以直接遍历类原型上的属性,不需要依赖实例:

class User {
  @key
  id: number;

  @maxlength(50)
  Name: string;
}

// 获取类上所有声明的属性,过滤掉constructor
const allProperties = Reflect.ownKeys(User.prototype).filter(key => key !== 'constructor');
for (const property of allProperties) {
  const decorators = Reflect.getMetadata(DECORATORS_META_KEY, User.prototype, property);
  console.log(`属性${String(property)}的装饰器列表:`, decorators);
}

注意事项

  • 元数据是存在类原型上的,和实例无关,所有实例共享同一份装饰器信息,不需要重复读取
  • 你可以根据需求自定义存入元数据的装饰器信息结构,比如增加更多参数、标识位等

内容的提问来源于stack exchange,提问作者Akelmj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 23:06:07