【问题标题】:Read and update object with Typescript compiler API使用 Typescript 编译器 API 读取和更新对象
【发布时间】:2020-04-14 17:18:20
【问题描述】:

typescript 编译器 API 对我来说是新的,看起来我错过了一些东西。 我正在寻找使用编译器 API 更新 ts 文件中特定对象的方法

现有文件 - some-constant.ts

export const someConstant = {
    name: 'Jhon',
    lastName: 'Doe',
    additionalData: {
        age: 44,
        height: 145,
        someProp: 'OLD_Value'
        /**
         * Some comments that describes what's going on here
         */
    }
};

毕竟,我想得到这样的东西:

export const someConstant = {
    name: 'Jhon',
    lastName: 'Doe',
    additionalData: {
        age: 999,
        height: 3333,
        someProp: 'NEW_Value'
        eyeColor: 'brown',
        email: 'someemail@gmail.com',
        otherProp: 'with some value'
    }
};

【问题讨论】:

  • 这是您想在编译时发射时做的事情,还是您想直接对源文件进行此更改?如果是后者,那么您可能需要查看ts-morph
  • 我需要直接在源文件上制作。我尝试了 ts-morph,也没有成功:(

标签: javascript typescript compiler-construction typescript-compiler-api


【解决方案1】:

我开始写一个关于如何使用编译器 API 执行此操作的答案,但后来我放弃了,因为它开始变得超长。

这很容易通过ts-morph 实现,只需执行以下操作:

import { Project, PropertyAssignment, QuoteKind, Node } from "ts-morph";

// setup
const project = new Project({
    useInMemoryFileSystem: true, // this example doesn't use the real file system
    manipulationSettings: {
        quoteKind: QuoteKind.Single,
    },
});
const sourceFile = project.createSourceFile("/file.ts", `export const someConstant = {
    name: 'Jhon',
    lastName: 'Doe',
    additionalData: {
        age: 44,
        height: 145,
        someProp: 'OLD_Value'
        /**
         * Some comments that describes what's going on here
         */
    }
};`);

// get the object literal
const additionalDataProp = sourceFile
    .getVariableDeclarationOrThrow("someConstant")
    .getInitializerIfKindOrThrow(ts.SyntaxKind.ObjectLiteralExpression)
    .getPropertyOrThrow("additionalData") as PropertyAssignment;
const additionalDataObjLit = additionalDataProp
    .getInitializerIfKindOrThrow(ts.SyntaxKind.ObjectLiteralExpression);

// remove all the "comment nodes" if you want to... you may want to do something more specific
additionalDataObjLit.getPropertiesWithComments()
    .filter(Node.isCommentNode)
    .forEach(c => c.remove());

// add the new properties
additionalDataObjLit.addPropertyAssignments([{
    name: "eyeColor",
    initializer: writer => writer.quote("brown"),
}, {
    name: "email",
    initializer: writer => writer.quote("someemail@gmail.com"),
}, {
    name: "otherProp",
    initializer: writer => writer.quote("with some value"),
}]);

// output the new text
console.log(sourceFile.getFullText());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 2018-08-31
    • 1970-01-01
    • 2019-09-18
    • 2019-12-24
    • 1970-01-01
    • 2019-03-02
    相关资源
    最近更新 更多