【问题标题】:How to reference type and make sure import is not stripped by typescript compiler如何引用类型并确保导入不会被打字稿编译器剥离
【发布时间】:2021-10-18 22:24:32
【问题描述】:

我正在编写一个 ts 转换器,它找到命名的类装饰器,然后替换装饰器的调用并传递一个映射,其中包含装饰类的所有道具的名称和类型,例如:

源文件:

import BigNumber from "bignumber.js";

@decorator()
class AClass {
   aProp: BigNumber;
}

输出:

import BigNumber from "bignumber.js";

@decorator({"aProp": BigNumber})
class AClass {
   aProp: BigNumber;
}

我从 PropertyDeclaration 获取道具名称和类型:

const clazzProps = [];
for (const childNode of clazz.members) {
    if (ts.isPropertyDeclaration(childNode)) {
       const type = typeChecker.getTypeAtLocation(childNode);
       if (type.isClass()) {
           clazzProps.push(ts.createPropertyAssignment(
              ts.createIdentifier(childNode.name.getText()),
              childNode.type.typeName
           );
       }
    }
}

到目前为止一切顺利,但是在从输出 js 文件中删除编译导入语句后,导致源文件中的 BigNumber 仅作为类型引用,而不是作为值引用。 我的问题是,如何正确检查 BigNumber 是否不仅仅是一个类型并确保不会剥离导入?

【问题讨论】:

    标签: typescript-compiler-api


    【解决方案1】:

    我知道有点晚了,但还是这样。

    Typescript 编译器有四个主要阶段——解析、绑定、类型检查和发出。绑定是解决标识符之间关系的地方,但转换发生在“发射”阶段。

    这意味着在转换发生的那一刻,打字稿已经知道BigNumber 仅在此上下文中用作类型,并且遵循它自己的规则,所有仅指向类型的导入都不会发送到 js。

    不幸的是,没有简单的解决方案,您可能需要在转换期间自行添加此导入。

    同样的用例和问题在这里解决了https://github.com/nestjs/graphql/blob/master/lib/plugin/visitors/model-class.visitor.ts

    它使用类型检查器解析属性类型并找到此类型指向的文件并将此路径存储在importsToAddPerFile中,而不是在updateImports中添加到源文件中。

    我通常不建议在转换中使用 TypeChecker(它速度较慢,可能在某些情况下不可用,并且如果您依赖它的转换很少,可能会产生奇怪的结果),并且对于简单的情况,您可能只需阅读导入的内容您已经拥有并手动重新创建它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 1970-01-01
      • 2018-05-24
      • 2019-11-17
      • 2020-08-02
      相关资源
      最近更新 更多