在 TypeScript 编译器 API 中插入任意文本并修改 NodeArrays

Rub*_*aXa 3 typescript typescript-compiler-api

// Input
class Foo {
    templateString = 'some value';
}

// Output
import __LIB__ from '@scope/lib/path/to/lib';

class Foo {
    templateString = (function compiledTemplate(deps) {
        // ...
        return result;
    })({lib: __LIB__});
}
Run Code Online (Sandbox Code Playgroud)

其实我有两个疑问:

  1. 如何从字符串创建 AST 片段?
  2. 如何添加导入?

PS我尝试了各种方法createSourceFilets.createImportDeclaration但它们都会导致这个或那个错误:[

Dan*_*ser 5

要添加任意文本,我知道的最好方法是createIdentifier与要插入的字符串一起使用。


要添加导入语句,请记住您正在更新树而不改变原始树。

ts.visitEachChildAPI 采用一个nodesVisitor专门对NodeArrays 进行操作的参数。通常,如果您不传入 a ,它将使用您为参数传递的第一个回调对每个innodesVisitor进行操作,但这里您特别希望对完整节点数组进行操作。NodeNodeArrayvisitor

在您的情况下,您对 aSourceFile的语句感兴趣(这是一个NodeArray<Statement>。您可以使用 创建导入createImportDeclaration,并SourceFile通过传入 a 来更新,nodesVisitor如下所示:

function addImport(statements: ts.NodeArray<ts.Statement>) {
    const importStatement = ts.createImportStatement(/*...*/);
    return ts.createNodeArray([importStatement, ...statements]);
}

visitEachChild(
    sourceFile,
    /*replace this with something that controls traversal*/ x => x,
    context, 
    addImport);
Run Code Online (Sandbox Code Playgroud)