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

TypeScript能否对自定义type类型实现反射获取结构元数据?

结论

原生TypeScript 无法直接实现你要的针对type类型别名的运行时反射能力。
核心原因是TypeScript的类型系统仅在编译阶段生效,所有type、interface这类类型构造在编译为JavaScript的过程中会被完全擦除,运行时不存在对应类型的任何元数据,自然没法直接读取到属性名、可选性、字段类型这类信息。

可行实现方案

虽然原生不支持,但可以通过以下几种方案达到完全相同的效果:

1. 运行时Schema方案(工程成本最低)

不要先定义TS类型再尝试获取反射信息,反过来先定义运行时可读取的Schema结构,再从Schema反向推导TS类型,就能同时满足编译期类型校验和运行时元数据读取的需求,Zod、io-ts这类库都是为这个场景设计的。
举个Zod实现示例:

import { z } from "zod";

// 先定义运行时可识别的枚举和对象Schema
const eNumSchema = z.nativeEnum({
  FOO: 0,
  BAR: 1
} as const);
const fooSchema = z.object({
  bar: z.string(),
  baz: z.number().optional(),
  qux: eNumSchema.optional()
});

// 反向推导TS类型,和你原本定义的type foo完全等价
type foo = z.infer<typeof fooSchema>;

// 运行时直接遍历Schema就能生成你需要的元数据结构
const metadata = {
  name: "foo",
  members: Object.entries(fooSchema.shape).map(([key, schema]) => ({
    key,
    optional: schema.isOptional(),
    definition: schema === eNumSchema ? "eNum" : schema._def.typeName.toLowerCase()
  }))
};

这种方案不需要额外配置TS编译工具链,类型和元数据自动对齐,不会出现改了类型忘了同步元数据的问题,是目前工业界最常用的实现方式。

2. 编译期AST静态分析

如果你一定要保留先写type的代码风格,可以开发自定义TS Transformer(转换器),在编译阶段扫描TS代码的AST(抽象语法树),识别你定义的枚举和type结构,自动生成对应的元数据代码插入到编译产物中,运行时就可以直接读取预生成的元数据。
这种方案灵活度最高,但开发和维护成本很高,需要自行处理类型引用、泛型、嵌套类型等各种复杂场景,也可以直接用ts-morph这类封装好的TS AST处理库减少重复工作量。

3. 改用Class+装饰器实现

如果你可以把type别名改成Class定义,可以配合reflect-metadata库,开启TS的emitDecoratorMetadata编译选项,通过装饰器标记类属性,运行时读取元数据。
但这种方案有明显局限:默认生成的装饰器元数据只能识别基础类型(string/number/boolean)的信息,枚举、自定义引用类型拿到的信息非常模糊,可选属性也需要额外加装饰器标记,灵活度远低于前两种方案。

注:你给出的预期元数据示例里最后一个成员的key存在笔误,应该是qux而不是bar。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:54:20