How to find all the types involved in a node?
export const TraceConfiguration = {
register(container?: IContainer): void {
Object.assign(Tracer, DebugTracer);
}
};
These types: IContainer, Tracer, DebugTracer for TraceConfiguration node.
or
export type BindingWithBehavior = IBinding & {
sourceExpression: BindingBehaviorExpression;
};
These types: IBinding, BindingBehaviorExpression for BindingWithBehavior node.
No matter what is the node (Variable, Class, Literal, ...) or where is the type (in Parameter, Block, Union, ... ).
I want to access all available type.getText() in the whole node.
Does exist any general way to find out whole types that are used in a node? or I should define a specific functionality for each use case.
@HamedFathi I think you could just do:
const types = new Set<Type>();
node.forEachDescendant(descendant => {
if (TypeGuards.isTypeNode(descendant))
types.add(descendant.getType());
});
// or in 4.2.0 (just released)
const types = new Set<Type>(node.forEachDescendantAsArray().filter(TypeGuards.isTypeNode).map(d => d.getType()));
That won't get all the implicit types in there though.
Side note: Using forEachDescendantAsArray is slightly more efficient than using getDescendants() because getDescendants() will return parsed out token nodes.
That won't get all the implicit types in there though.
May I ask you to give me an example for this?
const types = new Set<Type>(node.forEachDescendantAsArray().filter(TypeGuards.isTypeNode).map(d => d.getType()));
Looks amazing.
Oh sorry, I misread your question originally. You may have to do:
const types = new Set<Type>();
node.forEachDescendant(descendant => {
if (TypeGuards.isTypedNode(descendant) || TypeGuards.isIdentifier(descendant))
types.add(descendant.getType());
else if (TypeGuards.isReturnTypedNode(descendant))
types.add(descendant.getReturnType());
});
That will get implicit types as well. You may want to filter out any types when you're done (check Type#isAny())
@dsherret
I use your code as the following:
function isNotPrimitiveType(type: Type): boolean {
return (
!type.isAny() &&
!type.isUnknown() &&
!type.isNull() &&
!type.isNumber() &&
!type.isNumberLiteral() &&
!type.isString() &&
!type.isStringLiteral() &&
!type.isBoolean() &&
!type.isBooleanLiteral()
);
}
function getUsedTypes(node: Node): Type[] {
const result: Type[] = [];
const types = new Set<Type>();
node.forEachDescendant(descendant => {
if (TypeGuards.isTypedNode(descendant)
|| TypeGuards.isIdentifier(descendant))
types.add(descendant.getType());
else if (TypeGuards.isReturnTypedNode(descendant))
types.add(descendant.getReturnType());
});
types.forEach(type => {
if (isNotPrimitiveType(type)) {
result.push(type);
}
});
return result;
}
But I got an error on this:
public visitTemplate(expr: AST.TemplateExpression): void {
const { cooked, expressions } = expr;
const length = expressions.length;
this.text += '`';
this.text += cooked[0];
for (let i = 0; i < length; i++) {
expressions[i].accept(this);
this.text += cooked[i + 1];
}
this.text += '`';
}
descendant: { cooked, expressions } = expr and this is a VariableDeclaration with undefined type!!!
AST.TemplateExpression is a class.
Error: message:"Cannot read property 'flags' of undefined"

@HamedFathi could you post a reproducible example (something I can copy and paste to reproduce) and include the full error message? Thanks.
Most helpful comment
Oh sorry, I misread your question originally. You may have to do:
That will get implicit types as well. You may want to filter out
anytypes when you're done (checkType#isAny())