TypeScript
AST traversal
Learn AST traversal with forEachChild.
What is forEachChild?
ts.forEachChild(node, visitFn) visits every direct child of an AST node in order and calls visitFn for each. Combined with a recursive visit function it is the standard way to walk the whole tree.
import ts from "typescript";
const sf = ts.createSourceFile(
"app.ts", "const a = 1;", ts.ScriptTarget.Latest, true
);
function visit(node: ts.Node) {
console.log(ts.SyntaxKind[node.kind]);
ts.forEachChild(node, visit);
}
visit(sf);
SyntaxKind and type guards
Every node has a numeric .kind; ts.SyntaxKind[kind] gives its name. To test for specific node kinds you use type guards such as ts.isIdentifier, ts.isFunctionDeclaration and ts.isVariableStatement.
function visit(node: ts.Node) {
if (ts.isIdentifier(node)) {
console.log(node.text);
}
ts.forEachChild(node, visit);
}
Exercise Count identifiers
Create a source file from function topla(a: number, b: number): number { return a + b; } with ts.createSourceFile. Write a recursive visit function; count Identifier nodes with ts.isIdentifier and descend with ts.forEachChild. Print the total count.
Show example solution
import ts from "typescript";
const sourceText = "function topla(a: number, b: number): number { return a + b; }";
const sf = ts.createSourceFile("app.ts", sourceText, ts.ScriptTarget.Latest, true);
let count = 0;
function visit(node: ts.Node) {
if (ts.isIdentifier(node)) {
count++;
}
ts.forEachChild(node, visit);
}
visit(sf);
console.log(count);
Test yourself
-
What does ts.forEachChild(node, fn) do?
- Mutates the node's text
- Visits every child of a node in order
- Performs type checking
- Creates a new AST node
Show answer
Visits every child of a node in order — forEachChild passes each direct child of a node in order to the given function; it neither creates nodes nor mutates text.
-
Identifier text
function visit(node: ts.Node) {
if (ts.isIdentifier(node)) {
console.log(node.____);
}
ts.forEachChild(node, visit);
}
Show answer
function visit(node: ts.Node) {
if (ts.isIdentifier(node)) {
console.log(node.text);
}
ts.forEachChild(node, visit);
}
-
AST visit parts
- ts.forEachChild
- Walks child nodes
- node.kind
- Node kind number
- ts.SyntaxKind[kind]
- Gives the kind name
- ts.isIdentifier(node)
- Whether the node is an Identifier
Next lesson: Summary - Compiler API