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

TypeScript如何获取类的属性与类型(类似Python的__annotations__)

在TypeScript中获取类属性及类型(类似Python的__annotations__)

TypeScript的类型信息编译后会被擦除,无法直接在运行时获取,但可以通过以下几种方式实现类似需求:

1. 用装饰器结合元数据收集

借助reflect-metadata库和TypeScript装饰器语法,能在类属性上标记并存储类型元数据,运行时读取这些信息。

步骤:

  • 安装依赖:npm install reflect-metadata
  • 修改tsconfig.json开启相关配置:
    {
      "compilerOptions": {
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
      }
    }
    
  • 实现工具代码:
    import 'reflect-metadata';
    
    // 属性装饰器,自动收集类型元数据
    function Prop(target: any, propertyKey: string) {
      const type = Reflect.getMetadata('design:type', target, propertyKey);
      const props = Reflect.getMetadata('class:props', target.constructor) || {};
      props[propertyKey] = type;
      Reflect.defineMetadata('class:props', props, target.constructor);
    }
    
    // 获取类属性类型的工具函数
    function sometool(cls: any) {
      return Reflect.getMetadata('class:props', cls) || {};
    }
    
    class AnotherClass {}
    
    class A {
      @Prop
      public k: string;
      @Prop
      public o: number;
      @Prop
      public s: AnotherClass;
    }
    
    console.log(sometool(A));
    // 输出:{ k: [Function: String], o: [Function: Number], s: [class AnotherClass] }
    

2. 自定义TypeScript转换器在编译阶段生成信息

编写自定义转换器,编译时扫描类的属性类型,自动为类添加包含类型信息的静态属性,运行时直接调用。

示例效果:
编译后自动生成类似代码:

class A {
  public k: string;
  public o: number;
  public s: AnotherClass;

  static __annotations__ = {
    k: String,
    o: Number,
    s: AnotherClass
  };
}

function sometool(cls: any) {
  return cls.__annotations__;
}

这种方式无需运行时依赖,但需要配置TypeScript编译时使用自定义转换器,适合工程化场景。

3. 用代码生成工具预生成类型信息

利用ts-morph这类操作TypeScript AST的工具,在开发阶段扫描源码,生成包含类属性类型的辅助文件,运行时直接导入使用。

示例:

import { Project } from 'ts-morph';

const project = new Project();
const sourceFile = project.addSourceFileAtPath('./src/A.ts');
const classA = sourceFile.getClass('A');

const annotations: Record<string, string> = {};
classA?.getProperties().forEach(prop => {
  const typeName = prop.getType().getText();
  annotations[prop.getName()] = typeName;
});

// 生成辅助文件
project.createSourceFile('./src/annotations.ts', `
export const AAnnotations = ${JSON.stringify(annotations)};
`).save();

运行时导入AAnnotations即可获取属性类型信息。

注意事项

  • 基础类型(string/number等)运行时对应String/Number构造函数,注意区分原始类型和包装对象。
  • 自定义类的类型可直接获取到类的构造函数引用。
  • 装饰器方案适合轻量场景,转换器和代码生成方案更适配复杂工程,无需运行时依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 21:29:59