簡體   English   中英

如何在 TypeScript 編譯器 API 中獲取從另一個文件導入的屬性類型的類型信息?

[英]How to get type information of a property type imported from another file in TypeScript Compiler API?

如何從另一個文件中獲取類型為 class 的屬性聲明的類型信息?

// 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 class 的成員和 jsDocComments。 我可以使用checker.getTypeAtLocation獲取HtmlButtonElement的所有成員或屬性,但不能獲取member1: Person 我錯過了什么?

您應該檢查程序的診斷( 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

感謝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 注釋中獲取已解析的模塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM