TypeScript Compiler API:如何在没有绝对路径的情况下获取类型的完全限定名称?

Posted

技术标签:

【中文标题】TypeScript Compiler API:如何在没有绝对路径的情况下获取类型的完全限定名称?【英文标题】:TypeScript Compiler API: How to get fully qualified name of type without absolute path? 【发布时间】:2021-08-14 13:10:02 【问题描述】:

我正在尝试使用 TypeScript 的 TypeChecker API 创建一个处理特定类型的工具。我需要唯一标识特定类型——比如来自@angular/platform-browser 包的Angular 的DomSanitizer。我有以下代码来获取类型的完全限定名称

let type = typeChecker.getTypeAtLocation(node);
let fqn = typeChecker.getFullyQualifiedName(type.getSymbol());

但是,这会返回包含node_modules 目录绝对路径的名称,例如 "/home/user/project/node_modules/@angular/platform-browser/platform-browser".DomSanitizer

我想删除项目特定的部分,只保留 @angular/plaform-browser/platform-browser.DomSanitizer 之类的内容。我更喜欢使用 TypeScript API 而不是对这个值进行一些字符串操作,因为我希望 API 更健壮。

【问题讨论】:

如果有多个 API 副本(例如,两个不同版本的 lodash 被包含稍微不同类型的两个依赖项使用),应该是什么行为? @BenjaminGruenbaum 好问题。在这种情况下,我可以使用相同的 fqn。 我认为没有办法使用公共 API 来做到这一点。据我所知,您可以使用typeChecker.symbolToString 只获取DomSanitizer(这是getFullyQualifiedName 在内部使用的),但随后要获取模块名称,父符号在公共API 中不可用(symbol.parent ) 并且我看不到从解析名称到原始模块名称的方法(仅相反)。 【参考方案1】:

如果你知道项目根是什么,你可以使用NodeJS's path.relative 方法:

import * as path from 'path'

const type = typeChecker.getTypeAtLocation(node);
const fqn = typeChecker.getFullyQualifiedName(type.getSymbol());

const projectRoot = '/home/user/project/node_modules/'
const relativePath = path.relative(projectRoot, fqn)
console.log(relativePath) // should print @angular/plaform-browser/platform-browser.DomSanitizer

【讨论】:

以上是关于TypeScript Compiler API:如何在没有绝对路径的情况下获取类型的完全限定名称?的主要内容,如果未能解决你的问题,请参考以下文章

[TypeScript] Installing TypeScript and Running the TypeScript Compiler (tsc)

浅析TypeScript Compiler 原理

Typescript Compiler - 捆绑外部库

如何在 TypeScript 中使用 Relay Modern(babel-plugin-relay 和 relay-compiler)?

如何为 dotnet core(web Api) 代码更改以及 TypeScript 代码更改启用实时重新加载

TypeScript入门五:TypeScript的接口