4

The typescript compiler API is new for me and looks like I'm missing something. I'm looking the way to update specific object at ts file with compiler API

Existing file - 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
         */
    }
};

After all, I want to get something like this:

export const someConstant = {
    name: 'Jhon',
    lastName: 'Doe',
    additionalData: {
        age: 999,
        height: 3333,
        someProp: 'NEW_Value'
        eyeColor: 'brown',
        email: '[email protected]',
        otherProp: 'with some value'
    }
};
2
  • 1
    Is this something you want to do at compile time when emitting or are you wanting to make this change directly to the source file? If it's the latter then you may want to check out ts-morph. Commented Apr 14, 2020 at 17:47
  • I need to make it directly on the source file. And I tried ts-morph, with no success too :( Commented Apr 14, 2020 at 22:07

1 Answer 1

4

I started writing an answer on how to do this with the compiler API, but then I gave up because it was starting to get super long.

This is easily possible with ts-morph by doing the following:

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("[email protected]"),
}, {
    name: "otherProp",
    initializer: writer => writer.quote("with some value"),
}]);

// output the new text
console.log(sourceFile.getFullText());
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.