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

如何获取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:配置环境

  1. 安装依赖:
npm install reflect-metadata
  1. 修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:55:26