[英]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.