【问题标题】:How to get type information of a property type imported from another file in TypeScript Compiler API?如何在 TypeScript Compiler API 中获取从另一个文件导入的属性类型的类型信息?
【发布时间】:2020-05-19 12:50:40
【问题描述】:

如何从另一个文件中获取类型为类的属性声明的类型信息?

// person.ts

/**
 * @description Some description
 */
export class Person {
  name: string;
  constructor() { }
}
// group.ts

export class Group {
  member1: Person; // <-- Use TS typechecker to get info of Person class
  member2: Person;
  element: HTMLButtonElement; // <-- Getting all member and nodes for HtmlButtonElement using typechecker
  constructor() { }
}

使用 TypeScript 编译器 API

import ts from 'typescript';
const parsedCMD = ts.getParsedCommandLineOfConfigFile(
  `tsconfig.lib.json`,
  undefined,
  ts.sys as any
);
const files = parsedCMD.fileNames;
const program = ts.createProgram(files, parsedCMD.options);
const checker = program.getTypeChecker();
const sourceFile = program.getSourceFile('group.ts');

ts.forEachChild(sourceFile, (node: ts.Node) => {
  if (ts.isClassDeclaration(node)) {
    node.members.forEach(member => {
      if (ts.isPropertyDeclaration(member)) {
        const type = checker.getTypeAtLocation(member.name);
        console.log(type);
        /**
         * Output for element: HtmlButtonElement
         *
         * callSignatures: undefined
         * checker: {getNodeCount: ƒ, getIdentifierCount: ƒ, getSymbolCount: ƒ, getTypeCount: ƒ, 
         * getRelationCacheSizes: ƒ, …}
         * constructSignatures: undefined
         * flags: 524288
         * id: 74
         * members: undefined
         * numberIndexInfo: undefined
         * objectFlags: 2
         * properties: undefined
         * stringIndexInfo: undefined
         * symbol: SymbolObject {flags: 65, escapedName: "HTMLButtonElement", declarations: Array(2), * members: Map(20), parent: undefined, …}
         * Was able resolve Symbols and Nodes for HtmlButtonElement
         *
         */

        /**
         * Output for member1: Person
         * checker: {getNodeCount: ƒ, getIdentifierCount: ƒ, getSymbolCount: ƒ, getTypeCount: ƒ, 
         * getRelationCacheSizes: ƒ, …}
         * flags: 1
         * id: 4
         * intrinsicName: "error"
         * objectFlags: 0
         *
         * Getting error when using checker.getTypeAtLocation
         */
      }
    });
  }
});

我想在 member1 位置访问 Person 类的成员和 jsDocComments。我可以使用checker.getTypeAtLocation 获取HtmlButtonElement 的所有成员或属性,但不能获取member1: Person 的所有成员或属性。我错过了什么?

【问题讨论】:

    标签: typescript typescript-compiler-api


    【解决方案1】:

    您应该检查程序的诊断 (ts.getPreEmitDiagnostics(program))。您会发现以下错误以及其他错误:

    error TS2304: Cannot find name 'Person'.
    
    member1: Person;
             ~~~~~~
    

    所以在将Person 导入该文件后...

    import { Person } from "./person";
    

    ...您可以执行以下操作:

    ts.forEachChild(groupFile, node => {
      if (ts.isClassDeclaration(node)) {
        for (const member of node.members) {
          if (ts.isPropertyDeclaration(member) && member.name.getText(groupFile) === "member1") {
            const personType = typeChecker.getTypeAtLocation(member.name);
            console.log(typeChecker.typeToString(personType));
            for (const property of personType.getProperties()) {
              console.log(property.name);
            }
          }
        }
      }
    });
    

    输出:

    Person
    name
    

    【讨论】:

    • 我以为所有的希望都破灭了,直到我看到这个!我的打字稿程序有错误。
    【解决方案2】:

    感谢Daivd Sherret 的回答。 上面的问题是我的项目的简化版本,它没有我在项目设置中面临的根本原因。我能够解决它。

    因此,我的项目有多个库,其中包含单独的 tsconfig.lib.json 文件,该文件扩展了根 tsconfig.json 文件。基本上它是 Angular 的 Nrwl nx monorepo。它使用path: {} 来解析来自多个库的源代码。例如,

    "paths": {
      "@brand/lib1": ["dist/libs/lib1"],
      "@brand/lib2/*": ["libs/lib2/*"]
    },
    

    TypeScript 编译器 (createProgram) 无法从这些路径别名的导入路径中解析模块。调试sourceFile 并查看resolvedModules 属性,使用路径@brand/lib1@brand/lib2 的导入模块未定义。造成这些的原因是我使用了tsconfig.lib.json,它是一个单独的库配置文件,它缺少 "baseUrl": "../../../""rootDir": "../../../" 选项。

    添加这些选项后,我能够从 TyepChecker 及其所有成员和 jsDoc cmets 获取已解析的模块。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-21
      • 1970-01-01
      • 1970-01-01
      • 2019-07-27
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多