如何使用 Typescript Compiler API 解析类型引用?

jlk*_*iri 7 javascript typescript typescript-compiler-api

假设我有以下接口:

interface Person {
 name: string;
}

interface Attendee {
 person: Person;
 id: number;
}
Run Code Online (Sandbox Code Playgroud)

我已经弄清楚如何使用编译器 API 来提取每个属性类型的字符串表示形式,例如:

interface Person {
 name: string;
}

interface Attendee {
 person: Person;
 id: number;
}
Run Code Online (Sandbox Code Playgroud)

我是这样做的: https: //github.com/jlkiri/tsx-ray/blob/master/src/index.ts。它是类型检查器和类型检查器的
组合。typeToStringgetTypeOfSymbolAtLocation

不过,我想解析类似Person其定义的类型,以便我得到:

{ 
 Attendee: {
  person: {
   name: "string";
  },
  id: "number"
 }
}
Run Code Online (Sandbox Code Playgroud)

我可以使用 API 来轻松执行此操作,还是必须自己实现逻辑?

Yor*_*ram 0

检查ts-morph。我最近发现了它,它看起来很有前途。

这是可以完成您想要的操作的最小代码:

import {ClassDeclaration, Project} from 'ts-morph';

const project = new Project({);
project.addSourceFilesAtPaths("src/**/*.ts");
const allSourceFiles = project.getSourceFiles();

allSourceFiles.forEach(sourceFile => {
   const classes = sourceFile.getClasses();
   classes.forEach(cls => {
      console.log(`class ${cls.getName()} {`);
      const properties = cls.getProperties();
      properties.forEach(prop => {
         const type = prop.getType();
         if(type.isClassOrInterface()) {
            const typeSymbol = type.getSymbol();
            console.log(`    ${prop.getName()} : 
            ${typeSymbol?.getName()} {`);
            const clsDeclaration = typeSymbol?.getDeclarations()[0] as ClassDeclaration;
            const members = clsDeclaration.getMembers();
            members.forEach(m => {
            console.log(`        ${m.getText()}`);
            });
            console.log(`    }`);
        } else {
            console.log(`    ${prop.getName()} : ${type.getText()}`);
        }
     });
     console.log(`}`);
  });
})
Run Code Online (Sandbox Code Playgroud)

对于以下两个文件:

// ./src/property.ts
class Category {
  description: string;
  id: number;
}
export default Category;

// ./src/product.ts
import Category from './category';
class Product {
  name: string;
  price: number;
  category: Category;
}
export default Product;
Run Code Online (Sandbox Code Playgroud)

您将得到以下打印输出:

class Category {
    description : string
    id : number
}
class Product {
    name : string
    price : number
    category : Category {
        description: string;
        id: number;
    }
}
Run Code Online (Sandbox Code Playgroud)