## 1. Project Overview & Quickstart (dsherret/ts-morph)

## File: README.md

# 

[](https://github.com/dsherret/ts-morph/actions?query=workflow%3ACI)

Monorepo for [ts-morph](packages/ts-morph) and related projects.

## Packages

- [ts-morph](packages/ts-morph) - TypeScript Compiler API wrapper. Provides an easier way to programmatically navigate and manipulate TypeScript and JavaScript code.
- [@ts-morph/bootstrap](packages/bootstrap) - Separate library for getting quickly setup with the Compiler API.

## Resources

- [TypeScript AST Viewer](https://ts-ast-viewer.com)

---

## File: Readme.md

# 

[](https://github.com/dsherret/ts-morph/actions?query=workflow%3ACI)

Monorepo for [ts-morph](packages/ts-morph) and related projects.

## Packages

- [ts-morph](packages/ts-morph) - TypeScript Compiler API wrapper. Provides an easier way to programmatically navigate and manipulate TypeScript and JavaScript code.
- [@ts-morph/bootstrap](packages/bootstrap) - Separate library for getting quickly setup with the Compiler API.

## Resources

- [TypeScript AST Viewer](https://ts-ast-viewer.com)

---

## File: readme.md

# 

[](https://github.com/dsherret/ts-morph/actions?query=workflow%3ACI)

Monorepo for [ts-morph](packages/ts-morph) and related projects.

## Packages

- [ts-morph](packages/ts-morph) - TypeScript Compiler API wrapper. Provides an easier way to programmatically navigate and manipulate TypeScript and JavaScript code.
- [@ts-morph/bootstrap](packages/bootstrap) - Separate library for getting quickly setup with the Compiler API.

## Resources

- [TypeScript AST Viewer](https://ts-ast-viewer.com)

---

## File: docs/details/ambient.md

---
title: Ambient
---

## Ambient

Certain nodes in TypeScript can be ambient. For example, all nodes within a declaration file are ambient.

### Testing if ambient

Use `isAmbient()`:

```ts
classDeclaration.isAmbient(); // returns: boolean
```

This will do several checks to see if it's an ambient declaration.

### `declare` keyword

Check for the `declare` keyword:

```ts
classDeclaration.hasDeclareKeyword(); // returns: boolean
```

Or get the `declare` keyword if it exists:

```ts
classDeclaration.getDeclareKeyword();
```

Or set if it has a `declare` keyword:

```ts
classDeclaration.setHasDeclareKeyword(true);
classDeclaration.setHasDeclareKeyword(false);
```

---

## File: docs/details/async.md

---
title: Async
---

## Async

Certain nodes in TypeScript can have an `async` keyword modifier.

### Is async

A node can be tested if it's async using the `isAsync()` method:

```ts
functionDeclaration.isAsync(); // returns: boolean
```

### `async` keyword

Get the `async` keyword if it exists:

```ts
functionDeclaration.getAsyncKeyword();
```

### Set async

Set if the declaration is async using `setIsAsync`:

```ts
functionDeclaration.setIsAsync(true);
```

---

## File: docs/details/classes.md

---
title: Classes
---

## Class Declarations

Class declarations can be retrieved from source files, namespaces, or function bodies:

```ts
const classes = sourceFile.getClasses();
const class1 = sourceFile.getClass("Class1");
const firstClassWithConstructor = sourceFile.getClass(c => c.getConstructors().length > 0);
```

### Name

It's important to note that class declarations may not have a name. For example:

```ts
export default class {
  // etc...
}
```

For this reason, the methods like `.getName()` and `.getNameNode()` are nullable on `ClassDeclaration`.

### Add/Insert

Add or insert classes to a source file, namespace, or function like declarations by calling `addClass()`, `addClasses()`, `insertClass()`, or `insertClasses()`.

```ts
const classDeclaration = sourceFile.addClass({
  name: "ClassName",
});
```

### Remove

Call `.remove()`:

```ts
classDeclaration.remove();
```

### Extends expression

Will return [`ExpressionWithTypeArguments | undefined`](expressions):

```ts
const extendsExpression = classDeclaration.getExtends();
```

Set the extends expression:

```ts
classDeclaration.setExtends("BaseClass");
```

Remove it:

```ts
classDeclaration.removeExtends();
```

### Implements expressions

Will return [`ExpressionWithTypeArguments[]`](expressions):

```ts
const implementsExpressions = classDeclaration.getImplements();
```

Add or insert implements expressions:

```ts
classDeclaration.addImplements("Named");
classDeclaration.addImplements(["Named", "Aged"]);
classDeclaration.insertImplements(1, "Named");
classDeclaration.insertImplements(1, ["Named", "Aged"]);
```

Remove an expression:

```ts
classDeclaration.removeImplements(0); // index
classDeclaration.removeImplements(classDeclaration.getImplements()[0]); // node
```

### Base Types

Get the base types:

```ts
const baseTypes = classDeclaration.getBaseTypes(); // returns: Type[]
```

This is useful to use if you don't know if the class could possibly extend a mixin or a class.

### Base Class

Get the base class:

```ts
const baseClass = classDeclaration.getBaseClass(); // returns: ClassDeclaration | undefined
```

Note: This is not a useful method to use if the base could possibly be a mixin. If you expect mixins, then use `.getBaseTypes()`.

### Derived Classes

Will return all the class declarations that derive from the current class:

```ts
const derivedClasses = classDeclaration.getDerivedClasses();
```

### Constructor

Constructors can be retreived via `getConstructors`. This returns all the constructors in an ambient context, but will only return the
implementation constructor otherwise.

```ts
const constructors = classDeclaration.getConstructors();
```

Add or insert a constructor or constructors by calling `addConstructor()`, `addConstructors()`, `insertConstructor()`, or `insertConstructors()`.

```ts
const ctor = classDeclaration.addConstructor({
  /* options like parameters may go here */
});
```

### Methods

Get instance methods:

```ts
const instanceMethods = classDeclaration.getInstanceMethods();
const myMethod = classDeclaration.getInstanceMethod("myMethod");
const firstMethodWith2Params = classDeclaration.getInstanceMethod(m => m.getParameters().length === 2);
```

Get the static methods:

```ts
const staticMethods = classDeclaration.getStaticMethods();
const myStaticMethod = classDeclaration.getStaticMethod("myMethod");
const firstStaticMethodWith2Params = classDeclaration.getStaticMethod(m => m.getParameters().length === 2);
```

#### Add/Insert

Add or insert methods by using `insertMethods()`, `insertMethod`, `addMethod`, or `addMethods`:

```ts
const method = classDeclaration.addMethod({ isStatic: true, name: "myMethod", returnType: "string" });
```

#### Remove

Call `.remove()`:

```ts
method.remove();
```

### Properties

Get the instance properties (includes parameter properties):


```ts
const instanceProperties = classDeclaration.getInstanceProperties();
const myProperty = classDeclaration.getInstanceProperty("myProperty");
const myStringProperty = classDeclaration.getInstanceProperty(p =>
    Node.isPropertyDeclaration(p) && p.getType().getText() === "string");
```

Get the static properties:


```ts
const staticProperties = classDeclaration.getStaticProperties();
const myStaticProperty = classDeclaration.getStaticProperty("myStaticProperty");
const myStaticStringProperty = classDeclaration.getStaticProperty(p =>
    Node.isPropertyDeclaration(p) && p.getType().getText() === "string");
```

#### Add/Insert

Add or insert properties by using `insertProperties()`, `insertProperty`, `addProperty`, or `addProperties`:

```ts
const property = classDeclaration.addProperty({
  isStatic: true,
  name: "prop",
  type: "string",
});
```

Add or insert get accessors by using `insertGetAccessors()`, `insertGetAccessor`, `addGetAccessor`, or `addGetAccessors`:

```ts
const getAccessor = classDeclaration.addGetAccessor({
  name: "someNumber",
  returnType: "number",
  statements: ["return 5;"],
});
```

Add or insert set accessors by using `insertSetAccessors()`, `insertSetAccessor`, `addSetAccessor`, or `addSetAccessors`:

```ts
const setAccessor = classDeclaration.addSetAccessor({
  name: "someNumber",
  parameters: [{ name: "value", type: "number" }],
  statements: ["_someNumber = value;"],
});
```

#### Remove

Call `.remove()`:

```ts
propertyDeclaration.remove();
```

### Get members

Get all the members regardless of whether static or instance:

```ts
const allMembers = classDeclaration.getMembers();
```

Get instance members including parameter properties:

```ts
const instanceMembers = classDeclaration.getInstanceMembers();
```

Get static members:

```ts
const staticMembers = classDeclaration.getStaticMembers();
```

### Extracting an Interface

An interface declaration structure can be extracted from a class by calling `classDeclaration.extractInterface()`. For example:

```ts
// the passed in name is optional and defaults to the class name
const interfaceStructure = classDeclaration.extractInterface(`I${classDeclaration.getName()}`);
```

Alternatively the static interface declaration structure of a class can be extracted by calling:

```ts
const interfaceStructure = classDeclaration.extractStaticInterface(`${classDeclaration.getName()}Static`);
```

## Abstract

Nodes on a class may be abstract.

Get if it's abstract:

```ts
method.isAbstract(); // returns: boolean
```

Get the abstract keyword:

```ts
method.getAbstractKeyword(); // returns: node | undefined
```

Set if abstract:

```ts
method.setIsAbstract(true); // set as abstract
method.setIsAbstract(false); // set as not abstract
```

## Constructors

Constructors implement common functions found on function like declarations, but also include a scope.

## Methods

Explore the functionality available via auto-complete.

## Properties

Explore the functionality available via auto-complete.

## Get Accessors

If it exists, get the corresponding set accessor:

```ts
const setAccessor = getAccessor.getSetAccessor();
```

## Set Accessors

If it exists, get the corresponding get accessor:

```ts
const getAccessor = setAccessor.getGetAccessor();
```

---

## File: docs/details/comments.md

---
title: Comments
---

## Comments

_ts-morph_ parses out certain kinds of comments to make them easier to work with. This breaks away from the behaviour in the compiler API because although comments are not very important for compiling, they can be important for programmatic refactoring tasks.

- **Comment Ranges** - Comments the compiler api parses out.
- **Comment Nodes** - Comments ts-morph parses out in certain scenarios. They extend from `ts.Node`.

## Comment Ranges

Comment ranges are not part of the AST and are generated on request.

- **Leading:** Comments that preceed the node after the previous significant token—between `node.getPos()` and `node.getStart()`.
- **Trailing:** Comments following the node before the next siginificant token or newline.

WARNING: Since comments are generated on demand and not part of the AST, using one after a
subsequent manipulation to the source file will throw an error.

### Retrieving

Leading and trailing comment ranges can be retrieved from any node by calling:

```ts
const leadingComments = node.getLeadingCommentRanges();
const trailingComments = node.getTrailingCommentRanges();
```

### Information

Once you have a comment range, there are several self explanatory methods:

- `.getKind()` - Returns `SyntaxKind.SingleLineCommentTrivia` or `SyntaxKind.MultiLineCommentTrivia`.
- `.getPos()` - Position.
- `.getEnd()` - End position.
- `.getWidth()` - Width (`end - pos`)
- `.getText()` - Text.
- `.wasForgotten()` - Returns true if the node was forgotten because a manipulation occured to the source file or its associated node was forgotten.

### More Details

Read more about comments in the compiler API documentation here: https://github.com/Microsoft/TypeScript/wiki/Architectural-Overview#trivia

## Comment Nodes

These are nodes ts-morph parses out. They do not include all comments, but only the first comment on a line if there are no significant tokens on that line and only in certain contexts (ex. source file statements, class declaration body, function body, namespace body, etc..).

For example, in the following scenario:

```ts setup: let functionCall: any;
// do something
functionCall(); // ok
```

...only the first comment will be parsed out. The second comment is considered a trailing comment range of the function call.

### Retrieving

Comment ranges can be retrieved using various `#getXWithComments()` methods.

For example:

```ts setup: let classDec: any, interfaceDec: any;
sourceFile.getStatementsWithComments();
classDec.getMembersWithComments();
interfaceDec.getMembersWithComments();
objectLiteralExpression.getPropertiesWithComments();
```

They also may appear in the results of `#getChildren()` in certain scenarios. For example:

```ts
const children = sourceFile.getChildSyntaxListOrThrow().getChildren();
```

This extends the behaviour of the compiler API.

### Why?

The reason this is done is to make inserting before or after comments possible. For example, given the following source file:

```ts setup: let functionCall: any;
// 1
// 2
functionCall();
```

It is possible to insert a statement after the first comment by specifying `sourceFile.insertStatement(1, "// new comment");`, which would modify the source file to be:

```ts setup: let functionCall: any;
// 1
// new comment
// 2
functionCall();
```

### Removing Comments

To remove a comment node, call `#remove()` on it:

```ts
sourceFile.getStatementsWithComments()[0].remove();
```

This will remove the comment and any of its trailing comment nodes.

### Trailing comment ranges of comment nodes

Comment nodes may have trailing comment ranges. For example, given the following source file:


```ts
/* 1 */ // 2
```

...the text `/* 1 */` is considered the comment node, while `// 2` is the trailing comment range. `// 2` can be retrieved with the following code:

```ts
const secondComment = sourceFile.getStatementsWithComments()[0].getTrailingCommentRanges()[0];
```

---

## File: docs/details/decorators.md

---
title: Decorators
---

## Decorators

Decorators can be retrieved from class related nodes by calling the `getDecorators()` method.

```ts
const decorators = classDeclaration.getDecorators();
```

### Name

Get the name or fully qualified name of a decorator by using the `getName()` or `getFullName()` functions respectively.

For example, given the following code:

```ts setup: const obj: { decorator: any; };
@obj.decorator
class Identifier {
}
```

The following happens:

```ts
decorator.getName(); // "decorator"
decorator.getFullName(); // "obj.decorator"
```

### Decorator factory

Decorators with parenthesis (ex. `@decorator(3)`) are decorator factories, while decorators without (ex. `@decorator`) are not.

```ts
decorator.isDecoratorFactory(); // returns: boolean
```

Set as a decorator factory or not:

```ts
decorator.setIsDecoratorFactory(true);
```

### Arguments

Get the decorator's arguments by calling `.getArguments()`:

```ts
const args = decorator.getArguments(); // returns: Expression[]
```

Add and insert via `.addArgument(...)`, `.insertArguments(...)`, `.addArgument(...)`, or `.addArguments(...)`.

```ts
const args = decorator.insertArguments(1, ["5", "6"]);
```

And remove them by calling `.removeArgument()`:

```ts setup: const args: any;
// specify the index
decorator.removeArgument(0);
// or specify the argument node
decorator.removeArgument(args[0]);
```

### Type arguments

Get the decorator's type arguments by calling `.getTypeArguments()`:

```ts
const typeArgs = decorator.getTypeArguments(); // returns: TypeNode[]
```

Add and insert via `.insertTypeArgument(...)`, `.insertTypeArguments(...)`, `.addTypeArgument(...)`, or `.addTypeArguments(...)`.

```ts
const typeArgs = decorator.insertTypeArguments(1, ["string", "number"]);
```

And remove them by calling `.removeTypeArgument()`:

```ts setup: let typeArgs: TypeNode[];
// specify the index
decorator.removeTypeArgument(0);
// or specify the type argument node
decorator.removeTypeArgument(typeArgs[0]);
```

### Call expression

Decorator factories are call expressions. Get the call expression by calling:

```ts
const callExpression = decorator.getCallExpression(); // returns: CallExpression | undefined
```

### Add/Insert decorators

Decorators can be added or inserted by calling `addDecorator(decorator)`, `addDecorators(decorators)`, `insertDecorator(index, decorator)`, or `insertDecorators(index, decorators)`.

For example:

```ts
classDeclaration.addDecorator({
  name: "MyDecorator",
  arguments: ["3", `"some string"`],
});
```

### Remove decorators

Call `.remove()`:

```ts
decorator.remove();
```

---

## File: docs/details/documentation.md

---
title: JS Docs
---

## JS Docs

Certain nodes can have JS docs. For example:

```ts setup: interface Person {}
/**
 * Gets the name.
 * @param person - Person to get the name from.
 */
function getName(person: Person) {
  // ...
}
```

### Get all JS doc nodes

Get all the JS doc nodes by using `getJsDocs()`:

```ts
functionDeclaration.getJsDocs(); // returns: JSDoc[]
```

### Add/insert docs

Add or insert JS doc comments using the `addJsDoc()`, `addJsDocs()`, `insertJsDoc()`, and `insertJsDocs()` methods.

For example:

```ts
// adds /** Some description... */
const docNode = classDeclaration.addJsDoc({
});
// or to force it to be multi-line, add a newline to the front of the string
classDeclaration.addJsDoc({
});
// or with tags
classDeclaration.addJsDoc({
  tags: [{
    tagName: "param",
    text: "value - My value.",
  }],
});
```

### JSDoc Nodes

Get the description:

```ts
// Getting the node from the example at the top of this file.
const jsDoc = functionDeclaration.getJsDocs()[0];
jsDoc.getDescription(); // returns string: "Gets the name."
```

Get the tags:

```ts
const tags = jsDoc.getTags();
tags[0].getText(); // "@param person - Person to get the name from."
```

Get the inner text (the text without the surrounding comment):

```ts
jsDoc.getInnerText(); // "Gets the name.\n@param person - Person to get the name from."
```

---

## File: docs/details/enums.md

---
title: Enums
---

## Enums

Enums can be retrieved from source files, namespaces, or function bodies:

```ts
const enums = sourceFile.getEnums();
const enum1 = sourceFile.getEnum("Enum1");
const enum2 = sourceFile.getEnum(e => e.getMembers().length === 5);
```

### Add/Insert

Add or insert enums to a source file, namespace, or function like declarations by calling `addEnum()`, `addEnums()`, `insertEnum()`, or `insertEnums()`.

```ts
const enumDeclaration = sourceFile.addEnum({
  name: "EnumName",
  members: [{
    name: "member",
  }],
});
```

### Remove

Call `.remove()`:

```ts
enumDeclaration.remove();
```

### Get all members

Use `getMembers()`:

```ts
const members = enumDeclaration.getMembers();
```

### Get member

Use `getMember()`:

```ts
const member1 = enumDeclaration.getMember("member1");
const member2 = enumDeclaration.getMember(m => m.getValue() === 1);
```

### Add/Insert member

Members can be added by calling `addMember()`, `addMembers()`, `insertMember()`, or `insertMembers()`:

```ts
const member = enumDeclaration.addMember({
  name: "newMember",
  value: 10,
});
```

### Const enum

Check if it's a const enum via `isConstEnum()`:

```ts
enumDeclaration.isConstEnum(); // returns: boolean
```

Get the `const` keyword via `getConstKeyword()`:

```ts
enumDeclaration.getConstKeyword(); // returns: Node | undefined
```

Set if it's a const enum via `setIsConstEnum(value)`:

```ts
enumDeclaration.setIsConstEnum(true);
enumDeclaration.setIsConstEnum(false);
```

## Enum Members

```ts
const member = enumDeclaration.getMember("member");
```

### Value

The value can be retrieved whether it is implicitly or explicitly defined:

```ts
enumMember.getValue(); // returns: string | number
```

It can also be set to a number:

```ts
enumMember.setValue(5);
```

Or a string:

```ts
enumMember.setValue("string value");
```

### Removing

Call `remove()` on it:

```ts
enumMember.remove();
```

## 2. Official Technical Reference & Guides (dsherret/docs)

# GitHub Docs 
[](https://github.com/codespaces/new/?repo=github)

This repository contains the documentation website code and Markdown source files for [docs.github.com](https://docs.github.com).

GitHub's Docs team works on pre-production content in a private repo that regularly syncs with this public repo.

Use the table of contents icon  on the top right corner of this document to navigate to a specific section quickly.

## Contributing

We accept different types of contributions, including some that don't require you to write a single line of code. For detailed instructions on how to get started with our project, see [About contributing to GitHub Docs](https://docs.github.com/en/contributing/collaborating-on-github-docs/about-contributing-to-github-docs).

### Ways to contribute

On the GitHub Docs site, you can contribute by clicking the **Make a contribution** button at the bottom of the page to open a pull request for quick fixes like typos, updates, or link fixes.

You can also contribute by creating a local environment or opening a Codespace. For more information, see [Setting up your environment to work on GitHub Docs](https://docs.github.com/en/contributing/setting-up-your-environment-to-work-on-github-docs).



For more complex contributions, please open an issue using the most appropriate [issue template](https://github.com/github/docs/issues/new/choose) to describe the changes you'd like to see.

If you're looking for a way to contribute, you can scan through our [help wanted board](https://github.com/github/docs/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) to find open issues already approved for work.

### And that's it!

If you're having trouble with your GitHub account, contact [Support](https://support.github.com).

That's how you can easily become a member of the GitHub Docs community. :sparkles:

## READMEs

In addition to the README you're reading right now, this repo includes other READMEs that describe the purpose of each subdirectory in more detail:

- [content/README.md](content/README.md)
- [content/graphql/README.md](content/graphql/README.md)
- [content/rest/README.md](content/rest/README.md)
- [contributing/README.md](contributing/README.md)
- [data/README.md](data/README.md)
- [data/reusables/README.md](data/reusables/README.md)
- [data/variables/README.md](data/variables/README.md)
- [src/README.md](src/README.md)

## License

The GitHub product documentation in the assets, content, and data folders are licensed under a [CC-BY license](LICENSE).

All other code in this repository is licensed under the [MIT license](LICENSE-CODE).

When using the GitHub logos, be sure to follow the [GitHub logo guidelines](https://github.com/logos).

## Thanks :purple_heart:

Thanks for all your contributions and efforts towards improving the GitHub documentation. We thank you for being part of our :sparkles: community :sparkles:!