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

如何通过reflect-metadata获取对象属性的具体类型及替代方案?

解决方案:获取TypeScript对象类型详情并生成JSON Schema

首先说明问题根源:reflect-metadata的design:type元数据只能识别内置基础类型(如String、Array等构造函数),对于匿名对象类型,TypeScript编译后会丢失具体结构信息,所以只能拿到顶层的Object类型。

下面提供两种可行的解决方向:

一、构建时获取类型信息(推荐)

TypeScript在编译阶段完整保留类型信息,可借助编译工具或API直接从源码提取结构:

1. 用TypeScript Compiler API解析源码

写一个预处理脚本,遍历类文件的AST(抽象语法树),直接读取body属性的完整类型结构:

import * as ts from 'typescript';

// 初始化编译程序
const program = ts.createProgram(['./src/your-class-file.ts'], {
  strict: true,
  target: ts.ScriptTarget.ESNext
});

const sourceFile = program.getSourceFile('./src/your-class-file.ts');
if (!sourceFile) return;

// 遍历AST查找目标类和body属性
ts.forEachChild(sourceFile, node => {
  if (ts.isClassDeclaration(node)) {
    node.members.forEach(member => {
      if (ts.isPropertyDeclaration(member) && member.name.getText() === 'body') {
        const typeNode = member.type;
        if (typeNode && ts.isTypeLiteralNode(typeNode)) {
          // 提取body的所有子属性类型
          typeNode.members.forEach(typeMember => {
            if (ts.isPropertySignature(typeMember)) {
              const propName = typeMember.name.getText();
              const propType = typeMember.type?.getText();
              console.log(`body.${propName}: ${propType}`);
            }
          });
        }
      }
    });
  }
});

这个脚本可以在项目构建前执行,拿到完整类型结构后直接生成JSON Schema。

2. 用第三方工具typescript-json-schema

这个工具可以直接根据TypeScript类型生成标准JSON Schema,无需自己解析AST:
先安装依赖:

npm install typescript-json-schema --save-dev

然后写脚本生成Schema:

import * as TJS from 'typescript-json-schema';

// 配置选项
const settings = {
  required: true, // 标记必填字段
};

const compilerOptions = {
  strictNullChecks: true,
};

// 生成目标类的JSON Schema
const schema = TJS.generateSchema('./src/your-class-file.ts', 'MyClass', settings, compilerOptions);
console.log(JSON.stringify(schema, null, 2));

它会自动识别MyClass中body属性的所有子类型,输出完整的JSON Schema。

二、运行时替代方案

如果必须在运行时获取类型,需要将匿名对象改为显式结构:

1. 定义显式类代替匿名对象

把body的类型抽成独立类,配合reflect-metadata和装饰器递归获取类型:

import 'reflect-metadata';

class BodyType {
  name!: string;
  address!: string;
  favouriteThings!: string[];
}

const MyPropertyDecorator = (): PropertyDecorator => {
  return (target, property) => {
    const type = Reflect.getMetadata('design:type', target, property);
    console.log(`${property} 类型构造函数: ${type.name}`);
    // 可以进一步遍历BodyType的属性元数据,获取子类型
  };
};

class MyClass {
  @MyPropertyDecorator()
  body!: BodyType;
}

2. 用自定义装饰器标记子属性

如果不想额外定义类,可以给属性添加装饰器来记录类型:

import 'reflect-metadata';

// 自定义装饰器,标记属性类型
const PropType = (type: any) => {
  return (target: any, propertyKey: string) => {
    Reflect.defineMetadata('prop:type', type, target, propertyKey);
  };
};

// 定义带元数据的Body类
class Body {
  @PropType(String)
  name!: string;

  @PropType(String)
  address!: string;

  @PropType(Array)
  favouriteThings!: string[];
}

class MyClass {
  body!: Body;
}

// 运行时读取元数据
const bodyInstance = new Body();
Object.keys(bodyInstance).forEach(key => {
  const type = Reflect.getMetadata('prop:type', Body.prototype, key);
  console.log(`body.${key} 类型: ${type.name}`);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:30:51