I have a TypeScript file which I want transpiled to JavaScript. As part of this translation, I want to add a comment before every function and I was hoping to do this using the TypeScript Compiler API.
I tried two different approaches. One of them was to grab the SourceFile
and change its statements
, like this:
const program = ts.createProgram([args.input], {});
const srcFile = find(program.getSourceFiles(), (sourceFile) => !sourceFile.isDeclarationFile);
srcFile.statements = ts.createNodeArray(srcFile.statements.map((statement) => {
if (!ts.isFunctionDeclaration(statement)) {
return statement;
}
return ts.addSyntheticLeadingComment(
statement,
ts.SyntaxKind.MultiLineCommentTrivia,
"My long desired comment",
true,
);
}));
which gives me the following error:
TypeError: Cannot read property 'emitNode' of undefined
at getOrCreateEmitNode (/Users/.../node_modules/typescript/lib/typescript.js:52792:19)
at getOrCreateEmitNode (/Users/.../node_modules/typescript/lib/typescript.js:52801:17)
at setSyntheticLeadingComments (/Users/.../node_modules/typescript/lib/typescript.js:52918:9)
at Object.addSyntheticLeadingComment (/Users/.../node_modules/typescript/lib/typescript.js:52923:16)
at /Users/.../dist/index.js:26:15
at Array.map (<anonymous>)
at Object.<anonymous> (/Users/.../dist/index.js:21:60)
at Module._compile (internal/modules/cjs/loader.js:654:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
at Module.load (internal/modules/cjs/loader.js:566:32)
I tried printing the statement
right before the ts.addSyntheticLeadingComment
and the statement
is a FunctionDeclaration
, as expected, albeit missing the emitNode
field, which I would expect to be created by the getOrCreateEmitNode
function.
The second approach I tried is similar, but it runs into the same issue; rather than overwriting the original srcFile.statement
, I'm working with a printer, as follows:
const printer = ts.createPrinter(undefined, {
substituteNode: (hint, node) => {
if (ts.isFunctionDeclaration(node)) {
return ts.addSyntheticLeadingComment(
node,
ts.SyntaxKind.MultiLineCommentTrivia,
"My long desired comment",
true,
);
}
},
});
console.log(printer.printFile(srcFile));
which gives the same error as the previous code.
The TypeScript file I am trying to change is very simple:
function myFunc(a: number, b: number): number {
return a + b;
}
Substituting the node is not necessary. Remember that comments aren't part of the AST, so don't add them to the array of statements in the place of the existing function declaration. Instead, just call addSyntheticLeadingComment
on the node without using the return value.
For example, the following code works fine:
import * as ts from "typescript";
const file = ts.createSourceFile("test.ts", `function myFunc(a: number, b: number): number {
return a + b;
}`, ts.ScriptTarget.Latest, true);
const functionDec = file.statements.find(ts.isFunctionDeclaration)!;
ts.addSyntheticLeadingComment(functionDec, ts.SyntaxKind.MultiLineCommentTrivia,
"My long desired comment", true);
const printer = ts.createPrinter({ removeComments: false });
console.log(printer.printFile(file));
Outputs:
/*My long desired comment*/
function myFunc(a: number, b: number): number {
return a + b;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With