If we rewrite the examples from https://babel.dev/docs/babel-traverse into TypeScript:
import * as parser from "@babel/parser";
import {traverse, NodePath} from "@babel/traverse";
import * as t from "@babel/types";
const code = `function square(n) {
return n * n;
}`;
const ast = parser.parse(code);
traverse(ast, {
enter(path: NodePath) {
if (path.isIdentifier({ name: "n" })) {
// path: NodePath<t.Identifier>
// path.node: Identifier
path.node.name = "x";
}
},
});
traverse(ast, {
FunctionDeclaration: function(path: NodePath<t.FunctionDeclaration>) {
path.node.id.name = "x";
},
});
There is a critical class NodePath, which has the following functionalities:
- It stores the entire path from the root node to the current node;
- It provides a method
parent() that returns the parent NodePath;
- It provides mutation methods:
path.replaceWith(newNode)
path.remove()
path.insertBefore(nodes) and path.insertAfter(nodes)
path.replaceWithMultiple(nodes)
- It's covariant: a
NodePath<Identifier> is a NodePath<Expression>.
If we rewrite the examples from https://babel.dev/docs/babel-traverse into TypeScript:
There is a critical class
NodePath, which has the following functionalities:parent()that returns the parentNodePath;path.replaceWith(newNode)path.remove()path.insertBefore(nodes)andpath.insertAfter(nodes)path.replaceWithMultiple(nodes)NodePath<Identifier>is aNodePath<Expression>.