ts-morph
Structures
Simplified AST representations called structures can be retreived from and used to set many Node objects.
Getting structure
To get the structure of a node, call node.getStructure().
// example with a class declaration, but this also works on interfaces, enums, and many other nodes.
const classStructure = classDeclaration.getStructure(); // returns: ClassDeclarationStructure
In the example above, a class declaration like the following...
export class MyClass {
myProp = 5;
}
...would return the following structure object similar to the following:
{
isAbstract: false,
isExported: true,
name: "MyClass",
typeParameters: [],
constructors: [],
properties: [{
name: "myProp",
initializer: "5",
type: undefined,
isReadonly: false,
isStatic: false
}],
methods: []
}
Setting with structure
It's also possible to set the structure of a node with an existing structure:
classDeclaration.set(classStructure);
// sets the name
classDeclaration.set({ name: "NewName" });
// sets the properties
classDeclaration.set({ properties: [{ name: "newProperty" }] });
Or you can use the addX or insertX methods with a structure:
sourceFile.addClass({ name: "NewClass", ...classDeclaration.getStructure() });
Traversing structures
Structure type guards
Similar to static methods found on Node, there is also a Structure export that you can use to check certain information about a structure.
For example:
import { Structure } from "ts-morph";
// ...etc...
if (Structure.isExportable(structure))
structure.isExported = false;
forEachStructureChild
Similar to the compiler API's forEachChild, there is a forEachStructureChild method in ts-morph for navigating over a structure's children.
For example:
import { forEachStructureChild, SourceFileStructure, Structure } from "ts-morph";
const structure: SourceFileStructure = {
kind: StructureKind.SourceFile,
statements: [{
kind: StructureKind.Function,
name: "myFunction",
parameters: [{ name: "myParam" }],
}],
};
forEachStructureChild(structure, child => {
if (Structure.hasName(child))
console.log(child.name);
});
Outputs: "myFunction"
Structures with no kind
Some structures have optional kinds. For example, in parameters: [{ name: "myParam" }] above, specifying kind: StructureKind.Parameter in the parameter would be unnecessarily repetitive. However, when using forEachStructureChild, you probably want to know the kind of the structure in order to do certain operations. For this reason, forEachStructureChild will automatically add the correct kind property to structures that don't have one.
Finding a child structure
Note that unlike ts-morph's forEachChild, this function acts like the forEachChild in the compiler API and will return any truthy value returned in the second argument's function:
const firstClassDecStructure = forEachStructureChild(structure, child => Structure.isClass(child) ? child : undefined);