TypeScript 编译器 API:获取类型结构

TypeScript Compiler API: get type structure

是否有 API 方法从 TypeScript 编译器获取“触底”类型信息?示例:

interface User {
  id: number
  name: string
}

type NameOnly = Pick<User, 'name'>

type NameOnlyAliased = NameOnly

在 VSCode 中,如果我将鼠标悬停在 NameOnlyAliased 上,它会显示:

type NameOnlyAliased = {
    name: string;
}

我的问题是编译器 API 中是否有函数(或其他不应用别名语义的简单方法,Pick 等)来获取右侧的信息-上面 = 的手边,最好是作为数据(不仅仅是字符串),比如:

{
  NameAliasedOnly: {
    properties: {
      name: {
         type: 'string'
      }
    }
  }
}

用例是生成代码以根据类型定义创建 fast-check 任意项(如果已经存在,那就太棒了)。为此,我尝试使用 ts-json-schema-generator,但有些类型定义它无法处理。

我找到了解决办法。它不直接使用 TypeScript 编译器 API,而是使用优秀的 ts-morph library,一个编译器 API 的包装器,它简化了许多任务。这是一些示例代码,其中 test.ts 文件包含我上面问题中的示例代码。

import { Project, TypeFormatFlags } from 'ts-morph'

const project = new Project({
  tsConfigFilePath: 'tsconfig.json',
  skipAddingFilesFromTsConfig: true,
})
const file = 'test.ts'
project.addSourceFileAtPath(file)

const sourceFile = project.getSourceFile(file)

const typeAlias = sourceFile?.getTypeAlias('NameOnlyAliased')
if (typeAlias) {
  console.log(
    typeAlias
      .getType()
      .getProperties()
      .map(p => [
        p.getName(),
        p
          .getTypeAtLocation(typeAlias)
          .getText(
            undefined,
            TypeFormatFlags.UseAliasDefinedOutsideCurrentScope
          ),
      ])
  )
}

执行此脚本会根据需要提供输出 [ [ 'name', 'string' ] ]。对于更复杂的类型,您可以导航到类型层次结构。