Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

ts-clone-node

wessberg210.4kMIT4.0.0TypeScript support: included

A library that helps you clone Nodes from a Typescript AST

typescript, ast, node, clone, copy, duplicate

readme

Logo

A library that helps you clone Nodes from a Typescript AST

Downloads per month NPM version Dependencies Contributors code style: prettier License: MIT Support on Patreon

Description

The Typescript Compiler API is very powerful and comes with a lot of create and update functions that can be used for creating and updating nodes in Custom transformers while visiting a SourceFile. Under such circumstances, it is easy to run into problems if you reuse a Node in another part of the tree without properly cloning it, since the parent chain, as well as the pos and end values will have wrong values and will lead to malformed output after your transformations have been applied.

This can be cumbersome for example when you want to simply add or remove a specific modifier from an arbitrary node in a given position. This library exports a cloneNode function that makes it easy to deep-clone a Node from a Typescript AST without any faulty parent links. Additionally, you get a simple hook with which you can do simple things such as edit the top-level properties of the cloned object such as its modifiers, decorators, etc.

Features

  • Simple to use
  • Extensible
  • Supports dynamic TypeScript versions

Backers

Patreon

Patrons on Patreon

Table of Contents

Install

npm

$ npm install ts-clone-node

Yarn

$ yarn add ts-clone-node

pnpm

$ pnpm add ts-clone-node

Peer Dependencies

ts-clone-node depends on typescript, so you need to manually install this as well.

Usage

To clone a Node from a Typescript AST, all you have to do is:

import {cloneNode} from "ts-clone-node";

// Clone the Node
const clonedNode = cloneNode(someNode);

Configuration

Hooking into and altering transformations

You can pass in a hook that enables you to modify the clone, agnostic to the kind of Node it is. For example:

import {cloneNode} from "ts-clone-node";

// Clone the Node, and alter the modifiers such that they don't include a modifier pointing
// to the 'declare' keyword
const clonedNode = cloneNode(someNode, {
    hook: node => {
        return {
            modifiers: modifiers => ensureNoDeclareModifier(modifiers)
        };
    }
});

There is also a 'finalize' which is invoked after a node has been cloned at any recursive step from the top node, allowing you to perform final alterations or track the node for other purposes.

const clonedNode = cloneNode(someNode, {
    finalize: (clonedNode, oldNode) => trackSomething(clonedNode, oldNode)
});

Passing in a specific TypeScript version

You can use pass a specific TypeScript to use as an option to cloneNode:

cloneNode(someNode, {
    typescript: specialTypescriptVersion
});

This can be useful, for example, in an environment where multiple packages in the same project depends on different TypeScript versions and you're relying on cloneNode.

Passing in a specific NodeFactory

From TypeScript v4 and forward, a NodeFactory can be retrieved from a TransformationContext to signal which transformer was responsible for creating or altering nodes. If you want to pass a specific NodeFactory, you can pass it as an option to cloneNode:

cloneNode(someNode, {
    factory: nodeFactoryFromTransformationContext
});

Setting parent pointers

By default, when you clone a node, it won't update the parent pointers such that you and TypeScripts compiler APIs can traverse the parent tree. You can toggle this behavior with the setParents option:

cloneNode(someNode, {
    setParents: true
});

Setting original node pointers

By default, when you clone a node, it won't keep references to the original nodes recursively. You can toggle this behavior with the setOriginalNodes option:

cloneNode(someNode, {
    setOriginalNodes: true
});

Preserving comments

By default, when you clone a node, comments will be preserved as much as possible and added to the cloned nodes as emitNodes. You can toggle this behavior with the preserveComments option:

cloneNode(someNode, {
    preserveComments: false
});

Preserving symbols

By default, when you clone a node, it won't preserve symbols from the original nodes. You can toggle this behavior with the preserveSymbols option:

cloneNode(someNode, {
    preserveSymbols: true
});

Contributing

Do you want to contribute? Awesome! Please follow these recommendations.

Maintainers

Frederik Wessberg
Frederik Wessberg
Twitter: @FredWessberg
Github: @wessberg
Lead Developer

FAQ

What is the point of this library

If you've run into the kind of trouble I'm explaining here, you'll understand. If not, I'm happy for you. You can move along!

License

MIT © Frederik Wessberg (@FredWessberg) (Website)

changelog

4.0.0 (2024-09-25)

Features

  • add TypeScript v5.6 support (3135c4f)

3.0.0 (2023-08-02)

Features

  • add TypeScript v5.1 support (21bf22b)

2.0.4 (2023-01-09)

2.0.3 (2023-01-09)

2.0.2 (2023-01-09)

Bug Fixes

  • fix cloning type parameter declarations (0d3c1a1)

2.0.1 (2023-01-09)

Features

  • handle decorated members (b9b9791)

2.0.0 (2023-01-09)

Bug Fixes

Features

  • implement support for TypeScript v4.9 (988b10d)

1.0.0 (2022-05-30)

Features

  • Add TypeScript 4.7 support (bba8536)

0.3.32 (2022-04-12)

0.3.31 (2022-04-12)

0.3.30 (2022-01-03)

Bug Fixes

  • support Identifier nodes with only escapedText. #6 (9e5378c)

0.3.29 (2021-11-17)

Features

  • add TypeScript v4.5 support (972470a)

0.3.28 (2021-09-21)

Bug Fixes

  • fix cloning TupleTypeNodes on TypeScript 3.x (2243b29)

0.3.27 (2021-09-21)

0.3.26 (2021-09-21)

Bug Fixes

  • fix an issue where ArrayTypeNodes didn't have their TextSpan reset (b579487)

0.3.25 (2021-08-31)

Features

  • add TypeScript 4.4 support (0a004a8)

0.3.24 (2021-06-11)

Bug Fixes

  • property-access-chains: fix cloning of PropertyAccessChains. Fixes #5 (5497b6c)

0.3.23 (2021-05-29)

Bug Fixes

  • use provided modifiers when creating/updating MethodSignatures (b405dca)

0.3.22 (2021-05-29)

0.3.21 (2021-05-29)

0.3.20 (2021-05-28)

0.3.19 (2021-03-16)

Bug Fixes

  • add support for 4.1.0-beta and 4.1.0 nightly (a164d27)
  • ImportEqualsDeclaration: add support for constructing type-only ImportEqualsDeclarations, as supported by TypeScript 4.2 (c4b6082)
  • support @see jsdoc comments with TypeScript 4.1 (bc8d58c)

Features

  • ConstructorTypeNode: add support for the 'abstract' modifier for ConstructorTypeNodes, as introduced in TypeScript 4.2 (254292a)

0.3.16 (2020-10-20)

Features

  • MappedTypeNode: add support for 'as' clauses in MappedTypeNodes (9ddc790)
  • TemplateLiteralTypeNode: add support for TemplateLiteralTypeNode and TemplateLiteralTypeSpan (8478aea)

0.3.15 (2020-09-07)

0.3.14 (2020-08-23)

Features

  • JSDocDeprecatedTag: add support for JSDocDeprecatedTags (bd6df51)

0.3.13 (2020-08-11)

Bug Fixes

  • parentheses: make sure that cloned CallExpressions and VariableDeclarations are always structurally equivalent (03206f6)

Features

  • NamedTupleMember: add support for NamedTupleMembers (339fc9b)

0.3.12 (2020-08-07)

Bug Fixes

  • PropertyAssignment: make sure that cloned PropertyAssignments are always structurally equivalent. Closes #1 (fa59c75)

0.3.11 (2020-07-27)

Bug Fixes

  • comments: improve comment cloning (8f2dbcc)

0.3.10 (2020-07-27)

Bug Fixes

  • also clear synthetic trailing comment ranges (fe6052e)

0.3.9 (2020-07-03)

Features

  • typescript: add TypeScript v4 support (729b38e)

0.3.8 (2020-03-29)

Bug Fixes

  • when preserving a node, make sure to set the parent of the old node if requested (d78720d)

0.3.7 (2020-03-29)

Bug Fixes

  • fix an issue where the options for setParentNodes would be ignored (fcd3eb7)

0.3.6 (2020-03-29)

Bug Fixes

  • always set parents, traversable with _parent, unless 'setParents' is true, then the 'parent' property is used directly (6db6182)

0.3.5 (2020-03-29)

Features

  • setParents: expose 'setParents' function (4b8bda1)

0.3.4 (2020-03-01)

Bug Fixes

  • add support for PrivateIdentifiers (17068ef)

0.3.3 (2020-01-15)

Bug Fixes

  • typescript-3.8: respect 'isTypeOnly' property for ImportClauses (de62562)

0.3.2 (2020-01-14)

Features

  • typescript-3.8: add support for TypeScript v3.8 (36db665)

0.3.1 (2020-01-10)

Features

  • add more customizability (a40af21)

0.3.0 (2020-01-10)

0.2.1 (2020-01-07)

0.2.0 (2020-01-07)

Bug Fixes

  • add support for cloning comments (73887ae)

0.1.4 (2020-01-02)

Bug Fixes

  • fix issue with cloning MethodSignatures with modifiers (c392fc9)

0.1.3 (2019-12-28)

0.1.2 (2019-12-28)

Bug Fixes

  • ensure compatibility with TypeScript v3.0.0 (92139eb)

0.1.1 (2019-12-27)

0.1.0 (2019-12-27)

Features

  • add support for dynamic TypeScript versions (70fbbab)
  • add support for dynamic TypeScript versions (962a93b)