建议
🔍 搜索词
- getEmitResolver
- transform API
✅ 可实现性检查清单
我的建议符合以下指导原则:
- 这不会对现有的TypeScript/JavaScript代码造成破坏性的更改
- 这不会改变现有JavaScript代码的运行时行为
- 这可以在不根据表达式的类型发射不同的JS的情况下实现
- 这不是一个运行时特性(例如库功能、使用JavaScript输出的非ECMAScript语法、JS的新语法糖等)
- 这个特性将与 TypeScript's Design Goals 的其他部分一致。
⭐ 建议
transform
API非常方便,因为使用这个API不需要调用Program
来将ts
编译为js
以使用自定义AST转换器。然而,它不允许需要访问EmitResolver
的情况。如果transform
API可以让用户将getEmitResolver
传递到TransformationContext
中,那就太好了。
目前,getEmitResolver
既没有暴露给TransformationContext
接口,也没有暴露给Program
接口。
📃 激励示例
一个理想的示例应该是这样的
export function constructorParametersDownlevelTransform(program: ts.Program): ts.TransformerFactory<ts.SourceFile> {
const typeChecker = program.getTypeChecker();
const reflectionHost = new TypeScriptReflectionHost(typeChecker);
return (ctx: ts.TransformationContext) => {
return getDownlevelDecoratorsTransform(
typeChecker,
reflectionHost,
[],
false,
false,
true,
)({
...ctx,
getEmitResolver: ctx.getEmitResolver()
? ctx.getEmitResolver
: program.getDiagnosticsProducingTypeChecker().getEmitResolver,
});
};
}
💻 用例
我正在尝试实验这个想法:
- 使用
transform
API处理TypeScript源代码的AST,并使用一些自定义AST转换器。 - 使用
swc
或esbuild
将经过新转换的源代码编译为ts
。
据我所知,使用transform
API处理AST相当快。如果我可以在不使用Program
进行完整的编译步骤的情况下处理AST,而是使用swc
或esbuild
进行编译,那么这将有助于我实现目标:快速编译+源代码以我想要的方式进行处理(Jest提升、Angular下级构造函数等...)
5条答案
按热度按时间7kqas0il1#
@rbuckton,你有什么想法?
toe950272#
在谷歌,我们也会从将
EmitResolver
应用于转换器中受益。用例:为了在开发过程中提高编辑/刷新性能,我们希望将 TS 转译为 JS,而不进行类型检查。理想情况下,我们会使用
ts.transpileModule()
来实现这一点。然而,我们仍然需要进行一些转换,对于两种情况,我们看不到不使用类型检查器或发出解析器就能实现它们的方式:.default
访问导入,我们需要找到给定标识符的导入声明(代码)。EmitResolver#getReferencedImportDeclaration
在这里会有所帮助。EmitResolver#isReferencedAliasDeclaration
在这里会有所帮助。@rbuckton,你是否考虑将
EmitResolver
及其一些方法设为公共?jq6vz3qz3#
暴露程序的
EmitResolver
也会使诸如dts-bundle-generator
或@microsoft/api-extractor
等工具受益 - 在这种情况下,我们需要在生成新节点或更新现有节点时执行名称冲突解决,并尽可能保留用户的输入。如果不暴露任一程序的EmitResolver
或globalThis
符号,将会出现相当大的问题甚至不可能。仅供参考,
@microsoft/api-extractor
已经在使用内部方法来获取EmitResolver
以使用hasGlobalName
执行描述的检查。@andrewbranch@rbuckton 你是否对将其公开有任何顾虑?
cigdeys34#
EmitResolver
主要是针对TypeChecker
的一个关注发射的 Package 器。你几乎总是可以直接从检查器获取相同的信息,如果你正在使用我们的 API 运行自定义转换器,你已经可以访问检查器了。我更感兴趣的是,是否存在我们应该在TypeChecker
上公开的缺失功能。例如,与其仅仅为了访问hasGlobalName
而使EmitResolver
公开,我们可以相反地公开TypeChecker
现有的resolveName
方法以实现相同的功能,即:checker.resolveName(name, /*location*/ undefined, SymbolFlags.All, /*excludeGlobals*/ false)
。flvlnr445#
我们可以为相同的功能暴露TypeChecker现有的resolveName方法,即:checker.resolveName(name, /location/ undefined, SymbolFlags.All, /excludeGlobals/ false)。
@rbuckton 这个想法很有道理,谢谢!对于这个特定的用例,我可以创建一个打开此API的PR吗?