What is ts-morph?
The ts-morph package is a TypeScript compiler API wrapper that provides a simpler way to programmatically navigate, analyze, and manipulate TypeScript and JavaScript code. It abstracts the complexity of the underlying TypeScript compiler API, making it more accessible and easier to use for tasks such as code analysis, transformation, and generation.
What are ts-morph's main functionalities?
Navigating the AST
This feature allows users to navigate the Abstract Syntax Tree (AST) of a TypeScript file. The code sample demonstrates how to load a TypeScript file into a project, retrieve all classes from it, and log their names.
const project = new Project();
const sourceFile = project.addSourceFileAtPath('example.ts');
const classes = sourceFile.getClasses();
console.log(classes.map(c => c.getName()));
Modifying code
This feature enables users to programmatically modify TypeScript code. The code sample shows how to create a new TypeScript file, change the initializer of a variable declaration, and then log the updated source code.
const project = new Project();
const sourceFile = project.createSourceFile('example.ts', 'const a = 1;');
sourceFile.getVariableDeclaration('a').setInitializer('2');
console.log(sourceFile.getText());
Code generation
This feature is used for generating new code, such as classes, interfaces, or functions. The code sample illustrates how to create a new TypeScript file and add a new class to it.
const project = new Project();
const sourceFile = project.createSourceFile('example.ts');
sourceFile.addClass({ name: 'NewClass' });
console.log(sourceFile.getText());
Other packages similar to ts-morph
typescript
The 'typescript' package is the core TypeScript compiler itself. While ts-morph is built on top of it and provides a higher-level API for easier manipulation of TypeScript code, using the 'typescript' package directly requires more in-depth knowledge of the TypeScript compiler API.
jscodeshift
jscodeshift is a toolkit for running codemods over multiple JavaScript or TypeScript files. It provides a more scriptable interface for transforming code. Compared to ts-morph, jscodeshift is more focused on code transformations and less on detailed AST navigation or code generation.
babel
Babel is a widely used JavaScript compiler that allows developers to use next-generation JavaScript, today. It can be used for code transformations similar to ts-morph, but it's more focused on compiling modern JavaScript syntax to backwards-compatible versions. Babel's plugin system allows for powerful code transformations but requires more setup compared to ts-morph for TypeScript-specific tasks.
ts-morph
TypeScript Compiler API wrapper. Provides an easier way to navigate and manipulate TypeScript and JavaScript code.
Formerly ts-simple-ast
.
Library Development - Progress Update (20 April 2019)
There were a lot of breaking changes in v2.0. Please review breaking-changes.md and see the changelog for information on new features.
This library is still under early active development. Most common code manipulation/generation use cases are implemented, but there's still a lot of work to do.
Please open an issue if you find a feature missing or bug that isn't in the issue tracker.
Report
View a generated report on what nodes have been wrapped in the wrapped-nodes.md file.
Documentation
Work in progress: https://dsherret.github.io/ts-morph/
Getting Started
- Installing
- Instantiating
- Adding source files
- Getting source files
- Navigating
- Manipulating
Example
import { Project, StructureKind } from "ts-morph";
const project = new Project({
});
project.addExistingSourceFiles("src/**/*.ts");
const myClassFile = project.createSourceFile("src/MyClass.ts", "export class MyClass {}");
const myEnumFile = project.createSourceFile("src/MyEnum.ts", {
statements: [{
kind: StructureKind.Enum,
name: "MyEnum",
isExported: true,
members: [{ name: "member" }]
}]
});
const myClass = myClassFile.getClassOrThrow("MyClass");
myClass.getName();
myClass.hasExportKeyword();
myClass.isDefaultExport();
const myInterface = myClassFile.addInterface({
name: "IMyInterface",
isExported: true,
properties: [{
name: "myProp",
type: "number"
}]
});
myClass.rename("NewName");
myClass.addImplements(myInterface.getName());
myClass.addProperty({
name: "myProp",
initializer: "5"
});
project.getSourceFileOrThrow("src/ExistingFile.ts").delete();
project.save();
const compilerNode = myClassFile.compilerNode;
Or navigate existing compiler nodes created with the TypeScript compiler (the ts
named export is the TypeScript compiler):
import { createWrappedNode, ClassDeclaration, ts } from "ts-morph";
const classNode: ts.ClassDeclaration = ...;
const classDec = createWrappedNode(classNode) as ClassDeclaration;
const firstProperty = classDec.getProperties()[0];
Resources