【问题标题】: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
}
}`