我有一个TypeScript文件,我想将其转换为JavaScript。作为此翻译的一部分,我想在每个函数之前添加注释,我希望使用TypeScript编译器API来完成此操作。
我尝试了两种不同的方法。其中一个是抓住SourceFile
并更改其statements
,如下所示:
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,
);
}));
这给了我以下错误:
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)
我尝试在statement
之前打ts.addSyntheticLeadingComment
,statement
是FunctionDeclaration
,正如预期的那样,虽然错过了emitNode
字段,我期望由getOrCreateEmitNode
函数创建。
我尝试的第二种方法是类似的,但它遇到了同样的问题;而不是覆盖原始的srcFile.statement
,我正在使用打印机,如下所示:
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));
,它提供与前一代码相同的错误。
我想要更改的TypeScript文件非常简单:
function myFunc(a: number, b: number): number {
return a + b;
}
我真的很感激这方面的一些帮助。
祝你好运, 拉杜
答案 0 :(得分:1)
不需要替换节点。请记住,注释不是AST的一部分,因此请不要将其添加到语句数组中,而不要使用现有函数声明。相反,只需在节点上调用addSyntheticLeadingComment
,而不使用返回值。
例如,以下代码可以正常工作:
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));
输出:
/*My long desired comment*/
function myFunc(a: number, b: number): number {
return a + b;
}
答案 1 :(得分:0)
David Sherret's 答案是正确的,但无论我尝试什么,我总是遇到 Cannot read property 'emitNode' of undefined at getOrCreateEmitNode
错误。
事实证明我遗漏了 ts.createSourceFile
中名为 setParentNodes
的第四个参数。通过将此参数设置为 true,我可以使用 addSyntheticLeadingComment
。
基本上这个参数 (setParentNodes
) 设置每个 Node
的 parent
属性。
getOrCreateEmitNode
需要向上遍历树,没有父引用就不能这样做。有关 setParentNodes
的更多详细信息,请查看 this Github issue