首页 > 解决方案 > 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) {
  ???
}

标签: typescripttypescript-compiler-api

解决方案


我发现检查类型标志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);

推荐阅读