20

After I read the Using the Compiler API article, I could get the AST from string-code.

But when I try to generate the code (by escodegen) from AST (not transpile it) to code I got an error:

Unknown node type: undefined

Is there a way to generate the ast to the code?

import * as fs from "fs";
import escodegen from "escodegen";
import * as ts from "typescript";

const code = `
 function foo() { }
`;

const node = ts.createSourceFile("x.ts", code, ts.ScriptTarget.Latest);

console.log({ node });

const x = escodegen.generate(node);

console.log({ x });

codesandbox.io

2 Answers 2

17

You can do it by createPrinter and pass node to printNode.

Here working example:

const code = `
 function foo() { }
`;

const node = ts.createSourceFile("x.ts", code, ts.ScriptTarget.Latest);
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });

const result = printer.printNode(ts.EmitHint.Unspecified, node, node);
console.log(result); // function foo() { }

codesandbox

Sign up to request clarification or add additional context in comments.

Comments

7

I think it might help you:

import * as ts from "typescript";

const filename = "test.ts";
const code = `const test: number = 1 + 2;`;

const sourceFile = ts.createSourceFile(
    filename, code, ts.ScriptTarget.Latest
);

function printRecursiveFrom(
  node: ts.Node, indentLevel: number, sourceFile: ts.SourceFile
) {
  const indentation = "-".repeat(indentLevel);
  const syntaxKind = ts.SyntaxKind[node.kind];
  const nodeText = node.getText(sourceFile);
  console.log(`${indentation}${syntaxKind}: ${nodeText}`);

  node.forEachChild(child =>
      printRecursiveFrom(child, indentLevel + 1, sourceFile)
  );
}

printRecursiveFrom(sourceFile, 0, sourceFile);

OUTPUT:

SourceFile:  
-EndOfFileToken:  
SourceFile:  
-EndOfFileToken:  
SourceFile: const test: number = 1 + 2; 
-FirstStatement: const test: number = 1 + 2; 
--VariableDeclarationList: const test: number = 1 + 2 
---VariableDeclaration: test: number = 1 + 2 
----Identifier: test 
----NumberKeyword: number 
----BinaryExpression: 1 + 2 
-----FirstLiteralToken: 1 
-----PlusToken: + 
-----FirstLiteralToken: 2 
-EndOfFileToken:  

UPDATE

import * as ts from "typescript";

const code = `const test: number = 1 + 2;`;
const transpiledCode = ts.transpileModule(code, {}).outputText;
console.log(transpiledCode); // var test = 1 + 2;

Generate AST back to code

Please take a look here I know, this is not full answer, but it might help other people to answer this question.

Unfortunately, I have no time do dig deeper(

P.S. Code taken from here

3 Comments

In fact, I need the string-code. in my case I expect function foo() ..... so is there a way to generate back from ast to string?
In your update, it transpile. I want to regenerate (not transpile I said it in the question please)
@JonSud sorry, just don't have enough time to go deeper

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.