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

如何通过TypeScript AST/TypeChecker获取带完整属性的已解析类型

实现方案

你之前只拿到AST层面的信息,是因为没有调用TypeScript编译器的类型检查器能力,TS Playground展示的是类型推导完成后的结果,需要基于TS官方Compiler API的TypeChecker实现提取:

核心逻辑

  • 不要仅解析语法树,要初始化TS编译实例后获取类型检查器,拿到推导完成的Type对象,才能得到包含继承、泛型实例化、类型别名展开后的完整信息。
  • 对Type对象递归遍历所有属性,即可得到和Playground完全一致的结构化类型数据。
  • 如果你习惯使用ts-morph,可直接调用其封装的getType()相关方法,本质也是调用底层TS的TypeChecker能力,不用手动初始化编译项目。

关键实现代码

先安装依赖:
npm install typescript
参考代码示例:

import * as ts from 'typescript';

// 1. 初始化TS编译项目,配置和你项目的tsconfig保持一致
const program = ts.createProgram(['目标文件路径.ts'], {
  strict: true
});
const typeChecker = program.getTypeChecker();

// 2. 定位到你要提取类型的声明节点(示例为找指定名称的接口/类型别名)
const sourceFile = program.getSourceFile('目标文件路径.ts')!;
let targetTypeNode: ts.InterfaceDeclaration | ts.TypeAliasDeclaration | undefined;
ts.forEachChild(sourceFile, node => {
  if ((ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)) 
    && node.name.text === '你要提取的类型名') {
    targetTypeNode = node;
  }
});
if (!targetTypeNode) throw new Error('未找到目标类型');

// 3. 获取推导完成的完整类型对象
const targetType = typeChecker.getTypeAtLocation(targetTypeNode);

// 4. 遍历所有属性(包含继承得到的属性)
const allProperties = typeChecker.getPropertiesOfType(targetType);

// 5. 格式化得到结构化的类型信息
const parsedType = allProperties.map(propSymbol => {
  const propType = typeChecker.getTypeOfSymbolAtLocation(propSymbol, targetTypeNode!);
  return {
    name: propSymbol.name,
    type: typeChecker.typeToString(propType),
    isOptional: !!(propSymbol.flags & ts.SymbolFlags.Optional),
    isReadonly: !!(propSymbol.flags & ts.SymbolFlags.Readonly)
  };
});

console.log(parsedType);

扩展适配建议

如果需要处理联合类型、交叉类型、嵌套对象、泛型等复杂类型,可通过判断Type的flags属性区分类型类别,递归拆解嵌套结构即可。拿到完整的结构化类型信息后,你就可以对应实现JS对象和MongoDB BSON格式的自动转换逻辑,比如日期类型、数组类型、ObjectId类型的自动适配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:45:03