【问题标题】:typescript compiler api - How to detect if property type is enum or objecttypescript compiler api - 如何检测属性类型是枚举还是对象
【发布时间】:2022-02-09 08:51:21
【问题描述】:

我必须知道每个属性声明节点,是枚举还是其他对象。

所以我得到了类型参考:

 const typeReferance = (arrayType as any).typeName

但我不知道如何检测是枚举还是对象。

型号:

enum Color { Red, Green, Blue }
class SomeObject {
    string: string;
}
class Model {
    color:Color;
}

来访者:

if (node.kind === ts.SyntaxKind.PropertyDeclaration) {
  ???
}

【问题讨论】:

    标签: typescript typescript-compiler-api


    【解决方案1】:

    我发现检查 TypeFlags.Enum 的类型标志是不可靠的(可能是编译器 api 中的一个错误,但我有点懒得去研究它)。我所做的是获取ts.Type 的符号并检查其值声明是否为枚举声明。

    这是未经测试的,但应该给你基本的想法:

    function isEnumType(type: ts.Type) {
        // if for some reason this returns true...
        if (hasFlag(type.flags, ts.TypeFlags.Enum))
            return true;
    
        // it's not an enum type if it's an enum literal type
        if (hasFlag(type.flags, ts.TypeFlags.EnumLiteral) && !type.isUnion())
            return false;
    
        // get the symbol and check if its value declaration is an enum declaration
        const symbol = type.getSymbol();
        if (symbol == null)
            return false;
    
        const { valueDeclaration } = symbol;
        return valueDeclaration != null && valueDeclaration.kind === ts.SyntaxKind.EnumDeclaration;
    }
    
    function hasFlag(type: ts.Type, flag: ts.TypeFlags) {
        return (type.flags & flag) === flag;
    }
    

    检查它是否是一个对象更容易一些......

    function isObjectType(type: ts.Type) {
        return hasFlag(type.flags, ts.TypeFlags.Object);
    }
    

    顺便说一下,如果你不熟悉它,可以从类型检查器中检索节点的类型:

    const type = typeChecker.getTypeAtLocation(typeReference);
    

    【讨论】:

      【解决方案2】:

      我已经成功地尝试了“kind”属性,例如

      `   function visit(node: ts.Node) {
              if (!domain) {
                  return;
              }
      
              if (node.kind === ts.SyntaxKind.ClassDeclaration) {
                  //  console.log("Interface ignore");
                  domain.isClass = true;
              }
              if (node.kind === ts.SyntaxKind.EnumDeclaration) {
                  //  console.log("Interface ignore");
                  domain.isEnum = true;
              }
      
              if (node.kind === ts.SyntaxKind.InterfaceDeclaration) {
                  //  console.log("Interface ignore");
                  domain.isInterface = true;
                  return;
              }
              if (node.kind === ts.SyntaxKind.ImportDeclaration) {
                  //console.log("Import Ignore");
                  //output = null;
                  return;
              }
              if (node.kind === ts.SyntaxKind.DefaultKeyword) {
                  //console.log("DEFAULT");
                  return;
              }
              if (node.kind === ts.SyntaxKind.ExportKeyword) {
                  exportStatementFound = true;
                  //console.log("EXPORT");
                  return;
              }
      
      
              if (ts.isClassDeclaration(node) && node.name) {
                 //do something
              }
        }`
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-10
        • 2013-01-11
        • 1970-01-01
        • 2019-12-30
        • 1970-01-01
        • 2018-10-13
        • 2022-09-23
        • 2011-02-14
        相关资源
        最近更新 更多