typecript 编译器 API、检查器、getTypeCatalog?是否有可从检查器中获得的声明类型表?

问题描述

像这样初始化打字稿编译器 API 之后......

 const program = ts.createProgram(fileNames,options);
 const checker = program.getTypeChecker();

程序现在编译完成,这意味着打字稿程序已经遍历了整个程序一次,并且有机会构建了一个类型表。

在github上提供的typescript debug版本中,checker有功能...

ts.getTypeChecker().getTypeCatalog()

但是在发布版本上它不可用。

引用 limited documentation 中的内容,仅在概念层面进行描述,没有示例:

符号:命名声明。符号是绑定的结果。符号将树中的声明节点连接到对同一实体有贡献的其他声明。符号是语义系统的基本构建块。 类型:类型是语义系统的另一部分。类型可以是命名的(例如类和接口),也可以是匿名的(例如对象类型)。

TypeChecker 要做的第一件事是将来自不同 SourceFiles 的所有 Symbols 合并到一个视图中,并通过“合并”任何公共 Symbols(例如跨越多个文件的命名空间)来构建单个 Symbol Table。

初始化初始状态后,TypeChecker 准备回答有关程序的任何问题。这样的“问题”可能是:

这个节点的符号是什么? 这个符号的类型是什么? 在 AST 的这一部分中可以看到哪些符号? 函数声明有哪些可用的签名? 应该为文件报告哪些错误

TypeChecker 懒惰地计算一切;它只“解析”回答问题所需的信息。检查器只会检查有助于解决手头问题的节点/符号/类型,而不会尝试检查其他实体。

所以回答我自己的问题:是和否。

是的,因为“TypeChecker 将……将来自不同 SourceFiles 的所有符号合并到一个视图中”

不,因为“TypeChecker 懒惰地计算一切;它只“解析”回答问题所需的信息。”

ts.getTypeChecker() 上有几十个可用的函数 - 它们没有记录,并且在 the examples 中没有解析“深层”类型的用法示例。

我已成功使用 ts.getTypeChecker.forEachChild(...) 遍历文件,例如定位函数声明。但是手头有类型,我不知道如何使用检查器来解析类型并创建一个层次结构到基本类型。

解决方法

查找此信息的最佳位置是通过 TypeScript compiler's source code

getTypeCatalog 函数是内部的,而不是公共 API (source) 的一部分:

interface TypeChecker {
  // ...omitted...

  /* @internal */ getTypeCatalog(): readonly Type[];

  // ...omitted...
}

我不确定访问它是否有用。

我已经成功地使用 ts.getTypeChecker.forEach(...) 来遍历文件,例如,定位函数声明。但是手头有类型,我不知道如何使用检查器来解析类型并创建一个层次结构到基本类型。

我认为 forEach 上不存在 TypeChecker 函数(也许您指的是符号上的 forEach?)。

为此,您可以获取源文件 AST (program.getSourceFiles()),使用 sourceFile.forEachChild(child => { /* call child.forEachChild recursively */ }) 遍历它们,然后您可以使用 typeChecker.getTypeAtLocation(child) 获取类型。