Typescript编译器API-如何检测属性类型是枚举还是对象

时间:2019-03-08 03:58:59

标签: typescript typescript-compiler-api

我必须知道每个属性声明节点(如果是枚举或另一个对象)。

所以我得到类型引用:

 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) {
  ???
}

1 个答案:

答案 0 :(得分:0)

我发现检查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);