使用 Typescript 编译器读取和更新对象 API

Read and update object with Typescript compiler API

typescript 编译器 API 对我来说是新的,看起来我遗漏了什么。 我正在寻找使用编译器更新 ts 文件中特定对象的方法 API

现有文件 - 一些-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'
    }
};

我开始写一个关于如何用编译器做到这一点的答案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());