如何获取TypeScript类中指定变量的类型?
获取TypeScript类成员的声明类型
问题本质
你之前通过实例值获取类型的方法,只能拿到运行时实际值的类型,但TypeScript的类型信息在编译后会被擦除。像ID?: number = undefined这种可选属性,运行时实例的ID值是undefined,所以typeof只会返回undefined,无法还原声明时的number | undefined完整类型。
下面分两种场景给出解决方案:
编译时获取类型(纯类型层面)
如果只是需要在编译阶段拿到类成员的类型,直接用TypeScript内置的类型工具即可,完全不需要运行时代码:
class FakePerson { name: string = ""; age: number = 0; ID?: number = undefined; } // 定义类型工具 type GetVariableType<T, K extends keyof T> = T[K]; // 使用示例 type NameType = GetVariableType<FakePerson, "name">; // 类型为string type AgeType = GetVariableType<FakePerson, "age">; // 类型为number type IDType = GetVariableType<FakePerson, "ID">; // 类型为number | undefined
运行时获取类型(保留元数据)
如果需要在运行时拿到类型信息,得借助反射元数据来手动保留类型标记:
步骤1:配置环境
- 安装依赖:
npm install reflect-metadata
- 修改
tsconfig.json,开启装饰器和元数据支持:
{ "compilerOptions": { "emitDecoratorMetadata": true, "experimentalDecorators": true } }
步骤2:编写装饰器与工具函数
import "reflect-metadata"; // 装饰器:标记类成员并保存类型元数据 function TrackType(target: any, propertyKey: string) { // 获取TS自动生成的类型元数据 const rawType = Reflect.getMetadata("design:type", target, propertyKey); // 标记是否为可选属性(需配合自定义装饰器) const isOptional = Reflect.getMetadata("isOptional", target, propertyKey); // 保存自定义元数据 Reflect.defineMetadata("memberType", { rawType, isOptional }, target, propertyKey); } // 装饰器:标记可选属性 function Optional(target: any, propertyKey: string) { Reflect.defineMetadata("isOptional", true, target, propertyKey); } // 改造目标类,添加装饰器 class FakePerson { @TrackType name: string = ""; @TrackType age: number = 0; @TrackType @Optional ID?: number = undefined; } // 实现getVariableType函数 function getVariableType<T>(cls: new () => T, key: keyof T): string { const prototype = cls.prototype; const meta = Reflect.getMetadata("memberType", prototype, key as string); if (!meta) return "unknown"; // 映射TS类型名(比如把构造函数名Number转成number) const typeMap: Record<string, string> = { String: "string", Number: "number", Boolean: "boolean" // 可根据需要补充其他类型映射 }; const typeName = typeMap[meta.rawType.name] || meta.rawType.name; // 拼接可选属性的类型 return meta.isOptional ? `${typeName} | undefined` : typeName; } // 测试 console.log(getVariableType(FakePerson, "name")); // string console.log(getVariableType(FakePerson, "age")); // number console.log(getVariableType(FakePerson, "ID")); // number | undefined
内容的提问来源于stack exchange,提问作者jptrzy
相关产品推荐
相关产品推荐

