I want to add bar: true
to x
object using typescript AST.
This code cerates the bar: true
:
factory.createPropertyAssignment(
factory.createIdentifier("bar"),
factory.createTrue()
);
I know I need to return this function in order to add it to AST. if I do so then the problem is the code will override the foo: true
.
Any ideas how to add bar: true
without lose the foo: true
?
The code:
import * as ts from "typescript";
const code = `
const x = {
foo: true
})
`;
const node = ts.createSourceFile("x.ts", code, ts.ScriptTarget.Latest);
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
export const add = (context) => (rootNode) => {
function visit(node) {
const { factory } = context;
// if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) {
// return factory.createPropertyAssignment(
// factory.createIdentifier("bar"),
// factory.createTrue()
// );
// }
return ts.visitEachChild(node, visit, context);
}
return ts.visitNode(rootNode, visit);
};
const result = ts.transform(node, [add]);
// console.log({ result });
const transformedSourceFile = result.transformed[0];
const out = printer.printFile(transformedSourceFile);
console.log({ out });
If you're doing this in typescript, node.properties
is readonly. The type-safe way is to use the factory.update*()
methods when you want to mutate the current node and return it:
export const add: ts.TransformerFactory<ts.SourceFile> = (context) => (rootNode) => {
function visit(node: ts.Node): ts.VisitResult<ts.Node> {
const { factory } = context;
// using the provided typeguard to narrow the node kind
if (ts.isObjectLiteralExpression(node)) {
return factory.updateObjectLiteralExpression(node, [
// include the existing properties
...node.properties,
// add your generated property
factory.createPropertyAssignment(
factory.createIdentifier("bar"),
factory.createTrue()
)
]
);
}
return ts.visitEachChild(node, visit, context);
}
return ts.visitNode(rootNode, visit);
};