I've found checking the type flag for TypeFlags.Enum is not reliable (maybe a bug in the compiler api, but I've been kind of lazy to look into it). What I do is get the ts.Type's symbol and check if its value declaration is an enum declaration.
This is untested, but should give you the basic idea:
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;
}
Checking if it's an object is a little easier...
function isObjectType(type: ts.Type) {
return hasFlag(type.flags, ts.TypeFlags.Object);
}
By the way, in case you are not familiar with it, the type of a node can be retrieved from the type checker:
const type = typeChecker.getTypeAtLocation(typeReference);