简体   繁体   English

使用 TypeScript Compiler API 从类型引用节点获取类型别名声明节点

[英]Use TypeScript Compiler API to get the Type Alias Declaration Node from a Type Reference Node

I am working with ts-morph which in turns uses the TS Compiler API.我正在使用 ts-morph,它又使用 TS Compiler API。

I have this case of code:我有这样的代码案例:

export type Foo = string
export const foo: Foo = 'bar'

When I lookup the type for the export of foo I get string .当我查找foo的导出类型时,我得到string But what I actually want is the type alias declaration type.但我真正想要的是类型别名声明类型。

The Node type of the foo export is a VariableDeclaration. foo导出的节点类型是 VariableDeclaration。 From there I figured out how to get to the TypeReferenceNode .从那里我想出了如何到达TypeReferenceNode From there I have a method to get the name of the reference.从那里我有一个方法来获取引用的名称。 In this case "Foo" .在这种情况下"Foo" But I don't know how to go now from this name to the type alias declaration.但我现在不知道如何从这个名称转到类型别名声明。 Assume we don't know the location of "Foo" type alias.假设我们不知道"Foo"类型别名的位置。 How to find it out dynamically?怎么动态的找出来?

It's not possible in this specific situation.在这种特定情况下这是不可能的。 The TypeScript compiler interns certain types for performance reasons.出于性能原因,TypeScript 编译器会实习某些类型。

For performance reasons, we intern types where possible (this way we avoid duplicating work for equivalent types).出于性能原因,我们在可能的情况下实习类型(这样我们避免了对等效类型的重复工作)。 We do not currently intern anonymous object types, though we've experimented with it before.我们目前不实习匿名对象类型,尽管我们之前已经尝试过。 Unfortunately, interning object types has the side effect of breaking go to definition on the interned types;不幸的是,实习对象类型具有破坏实习类型定义的副作用; so we didn't pull it in. The specific types we intern today are indexed accesses, unions, and intersections (also reverse mapped types, but only inference can produce those).所以我们没有引入它。我们今天实习的特定类型是索引访问、联合和交叉(也是反向映射类型,但只有推理才能产生这些)。 This is a tradeoff - origin information is lost on interned types;这是一种权衡 - 实习类型的来源信息丢失; but we do avoid quite a bit of work most of the time.但大多数时候我们确实避免了相当多的工作。 - Source - 来源

So here, Foo is being interned as string since they're equivalent.所以在这里, Foo被作为string实习,因为它们是等价的。 I asked in the TypeScript repo if it would be feasible to disable this behaviour for analysis reasons, but didn't get a response yet.我在 TypeScript 存储库中询问出于分析原因禁用此行为是否可行,但尚未得到响应。

One trick you can do to get this to work is change the code to use a brand instead of only string .您可以做的一个技巧是将代码更改为使用品牌而不是仅使用string

export type Foo = string & { __FooBrand?: undefined };
export const foo: Foo = 'bar';

Additional links:附加链接:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM