如何遍历TypeScript类的声明成员并获取其名称与类型?
如何遍历类的未实例化成员并获取成员名称与类型
一、遍历类的未实例化成员
在JavaScript/TypeScript中,仅声明但未初始化的类属性不会出现在实例或类的原型上,所以直接遍历实例是拿不到这些成员的。要获取它们,有两种实用方案:
方案1:用装饰器收集属性名
通过自定义装饰器标记每个类属性,在装饰器逻辑里收集属性名称,就能在运行时轻松获取所有声明的成员:
// 存储类与对应属性名的映射 const classPropertyMap = new Map<Function, string[]>(); // 定义属性装饰器 function TrackProperty(target: any, propertyKey: string) { const constructor = target.constructor; if (!classPropertyMap.has(constructor)) { classPropertyMap.set(constructor, []); } classPropertyMap.get(constructor)!.push(propertyKey); } // 给目标类的属性添加装饰器 class Test { @TrackProperty a: number; @TrackProperty b: boolean; @TrackProperty c: string; } // 运行时获取所有未初始化的成员名称 console.log(classPropertyMap.get(Test)); // 输出: ['a', 'b', 'c']
方案2:通过TS AST工具解析源代码
使用ts-morph这类工具直接解析TypeScript源代码,提取类的属性信息(无需依赖运行时装饰器):
import { Project } from "ts-morph"; // 初始化项目并加载目标文件 const project = new Project(); const sourceFile = project.addSourceFileAtPath("./your-test-file.ts"); // 获取目标类并提取属性名 const testClass = sourceFile.getClass("Test")!; const propertyNames = testClass.getProperties().map(prop => prop.getName()); console.log(propertyNames); // 输出: ['a', 'b', 'c']
二、获取成员名称与对应类型
TypeScript的类型信息在编译为JavaScript后会被完全擦除,所以运行时无法直接获取属性的类型。根据你的需求,分两种场景处理:
场景1:编译时获取类型信息(仅用于类型检查)
如果只需要在编译阶段获取类型映射,可以用TypeScript内置的类型工具:
class Test { a: number; b: boolean; c: string; } // 生成属性名到类型的映射类型 type TestPropertyTypes = { [K in keyof Test]: Test[K]; }; // 这个类型等价于 { a: number; b: boolean; c: string; }
你可以用这个类型做编译时的类型推断、约束等操作,但无法在运行时输出类型字符串。
场景2:运行时获取类型信息
要在运行时同时拿到属性名和类型,只能通过解析源代码的方式(比如用ts-morph):
import { Project } from "ts-morph"; const project = new Project(); const sourceFile = project.addSourceFileAtPath("./your-test-file.ts"); const testClass = sourceFile.getClass("Test")!; const properties = testClass.getProperties(); properties.forEach(prop => { const name = prop.getName(); const type = prop.getType().getText(); console.log(`成员名称: '${name}', 对应类型: '${type}'`); }); // 输出结果: // 成员名称: 'a', 对应类型: 'number' // 成员名称: 'b', 对应类型: 'boolean' // 成员名称: 'c', 对应类型: 'string'
为什么直接实例化遍历失败?
你尝试实例化类后遍历没成功,是因为TypeScript中仅声明未初始化的属性,编译为JavaScript后不会被添加到实例或原型上。比如new Test()生成的实例,其Object.keys()结果是空数组——因为实例上根本没有这些属性,自然遍历不到。
内容的提问来源于stack exchange,提问作者AnArrayOfFunctions
相关产品推荐
相关产品推荐

