ts-morph Documentation

repository·latest·Indexed 27 days ago

https://github.com/dsherret/ts-morph

A high-level wrapper around the TypeScript Compiler API designed to make programmatic code navigation and manipulation of TypeScript and JavaScript code easier and more intuitive. It provides features such as in-memory change tracking, helper methods for modifying files, and the ability to fall back to underlying compiler API objects.

Tokens
60.3K
Snippets
220
Records
430
Agent score
90%

What's inside ts-morph

  1. Overview of ts-morph

    latest

    ts-morph is a wrapper around the TypeScript Compiler API. It provides an easier way to programmatically navigate and manipulate TypeScript and JavaScript code.

    Key features include:

    • Helper methods for getting information and programmatically changing files.
    • Ability to fall back to underlying compiler API objects (e.g., via .compilerNode or .compilerObject).
    • In-memory change tracking: all changes (including file/directory moves) are kept in memory until you explicitly call project.save() to write to the file system.
    • Text-based manipulations that allow wrapped nodes to be maintained between operations.
  2. Understand Wrapped Nodes in ts-morph

    latest

    In ts-morph, nodes are categorized as either 'wrapped' or 'unwrapped'.

    • Wrapped Nodes: These nodes include helper methods for advanced navigation and manipulation within the AST.
    • Unwrapped Nodes: These nodes are still treated as Node objects but lack the specialized helper methods provided by more specific node types. They are essentially the base Node type without the extended API.

    If you encounter a node that lacks the expected helper methods for navigation or manipulation, it is likely an unwrapped node. The library is being incrementally updated to wrap more nodes over time.

  3. Getting Started with ts-morph

    latest

    To use ts-morph, follow these general steps:

    1. Install the package.
    2. Instantiate a Project.
    3. Add source files to the project (either by path or by creating them).
    4. Navigate the source files and their nodes (classes, interfaces, etc.).
    5. Manipulate the code (rename, add properties, add interfaces, etc.).
    6. Save changes to the file system using project.save().
  4. Resolve source file dependencies

    latest

    When adding files via tsconfig.json, ts-morph automatically analyzes and includes dependent source files. You can skip this analysis by setting skipFileDependencyResolution: true in the Project constructor.

    If you are adding files using other methods (like globs or paths) and want to ensure all dependencies are included, call project.resolveSourceFileDependencies() after all files have been added.

    const project = new Project();
    
    // add everything to the project
    project.addSourceFilesFromTsConfig("dir1/tsconfig.json");
    project.addSourceFilesFromTsConfig("dir2/tsconfig.json");
    project.addSourceFilesAtPaths("dir3/**/*{.d.ts,.ts}");
    
    // resolve and add the dependent source files to the project
    project.resolveSourceFileDependencies();
  5. Format individual nodes

    latest

    Instead of formatting an entire file, you can target specific nodes (such as a single statement within a method) and call formatText() on them to selectively format only that portion of the code.

    project.getSourceFileOrThrow("file.ts")
      .getClassOrThrow("MyClass")
      .getInstanceMethodOrThrow("myMethod")
      .getStatements()[0]
      .formatText();
  6. Configure compiler options for In-Memory File Systems

    latest

    When using an in-memory file system, standard types may resolve to any because the default script target is ES5. To resolve types correctly (e.g., Set<string>), you must explicitly specify the lib compiler option or a higher target in the Project configuration.

    import { Project, ts } from "ts-morph";
    
    // Option 1: Specify specific lib files
    const projectLib = new Project({
      useInMemoryFileSystem: true,
      compilerOptions: {
        lib: ["lib.es2015.d.ts"],
      },
    });
    
    // Option 2: Specify a target that implicitly loads required libs
    const projectTarget = new Project({
      useInMemoryFileSystem: true,
      compilerOptions: {
        target: ts.ScriptTarget.ES2015,
      },
    });
    
    // Option 3: Include all lib files
    const projectFull = new Project({
      useInMemoryFileSystem: true,
      compilerOptions: {
        lib: ["lib.esnext.full.d.ts"],
      },
    });
  7. Configure Manipulation Settings in Project

    latest

    When initializing a new Project object, you can define manipulationSettings to control how code transformations (like renaming or adding imports) are applied. You can provide a full or partial configuration object.

    Available settings include:

    • indentationText: Controls indentation style (IndentationText.TwoSpaces, IndentationText.FourSpaces, IndentationText.EightSpaces, or IndentationText.Tab).
    • newLineKind: Controls line endings (NewLineKind.LineFeed or NewLineKind.CarriageReturnLineFeed).
    • quoteKind: Controls quote usage (QuoteKind.Single or QuoteKind.Double).
    • usePrefixAndSuffixTextForRename: Boolean determining whether to change shorthand property assignments to property assignments and add aliases to import/export specifiers.
    • useTrailingCommas: Boolean determining whether to use trailing commas in multi-line scenarios.
    import { IndentationText, NewLineKind, Project, QuoteKind } from "ts-morph";
    
    const project = new Project({
      manipulationSettings: {
        indentationText: IndentationText.FourSpaces,
        newLineKind: NewLineKind.LineFeed,
        quoteKind: QuoteKind.Double,
        usePrefixAndSuffixTextForRename: false,
        useTrailingCommas: false,
      },
    });