基于实现解析泛型类型



我目前正在尝试构建一个工具,我需要为我的最终输出解析泛型类型。

请注意,我使用的是ts-morph库。

为例,给定以下源,classAClassDeclaration为"入口点";对于爬行类型:

type X<T> = { fieldInType: T };
interface Y<T> {
fieldInInterface: T;
}
class classB<T> {
fieldInB?: T;
myFunction(a: T): void { //do something here }
}
class classA extends ClassB<string> {
interfaceField?: Y<string>;
typeField?: X<string>;
}

我希望得到这样的输出:

types of classA:
- interface Y { fieldInInterface: string } (from interfaceField)
- type X = { fieldInType: string }  (from typeField)
- string (from fieldInB in parentClass)
- myFunction(a: string): void (from myFunction in parentClass) 

我不确定如何正确地处理这个问题。目前,我正在递归地爬行所有类型,从基类开始(我使用getclass.getBaseClass()也递归地爬行基类,我希望这是正确的/最简单的方法)。

对于泛型类型,我执行以下操作:

  1. 等待,直到在爬行过程中遇到泛型类型(例如,在类中,或类中的类型别名),检查它是否有类型参数。
  2. 如果是,通过跳转到类型定义获得相应的类型参数(例如,使用getBaseClass()跳转到基类或使用getSymbol()getAliasSymbol()跳转到接口/别名类型)
  3. 遍历所有类型参数并获得相应的类型参数。
  4. 检查类型参数本身是否在映射中有一个条目(在下一点解释)。如果是,则将type参数替换为解析后的类型。(这是递归需要的定义泛型)
  5. 为每一对保存一个映射,即第i个类型参数的符号到类型参数
  6. 中的类型

对不起,我没有发布一个完整的代码样本,但我还没有这个完整的实现。

我的问题:

  1. 这是正确的方法吗?还是有一些神奇的typescript-compiler/ts-morph我忽略的那个函数正好达到了这个效果?
  2. 我看到有一个typeChecker.getTypeOfSymbolAtLocation(..),但我不确定如何确切地使用它,如果它有助于我的用例。

是的,我想你会发现getTypeAtLocationgetTypeOfSymbolAtLocation很有用。

查看ts-ast-viewer.com上的示例,然后在开发控制台中运行此命令:

{
const classANode = sourceFile.statements[3];
const classAType = checker.getTypeAtLocation(classANode);
for (const prop of classAType.getProperties()) {
const type = checker.getTypeOfSymbolAtLocation(prop, classANode);
console.log(prop.escapedName, checker.typeToString(type));
}
}

最新更新