'`recast` - adding a properties to an object
I want to modify properties to a particular typescript object with the library recast
.
This is the file content:
// /path/to/my/file.ts
...
import somelib from 'somelib';
...
export const theobj:MyType = {
thekey: {
prop1: 5,
prop2: 6
}
}
...
I want to remove prop1
and add a prop3
to prop thekey
inside the object theobj
.
This is my code:
import fs from 'fs';
import * as recast from 'recast';
const source = fs.readFileSync('/path/to/my/file.ts', 'utf-8');
const ts_ast = recast.parse(source, {
parser: require("recast/parsers/typescript")
});
const all = ts_ast.program.body;
for(const node of all){
if(node.type === recast.types.namedTypes.ExportNamedDeclaration.toString()){
const variable_declaration = node.declaration;
const variable_declarator = variable_declaration.declarations[0];
if(variable_declarator.id.name === 'theobj'){
for(const prop_def of variable_declarator.init.properties){
if(prop_def.key.name === 'theykey'){
for(let i = 0; i < prop_def.value.properties.length; i++){
const prop_obj = prop_def.value.properties[i];
if(prop_def.key.name === 'prop1'){
delete prop_def.value.properties[i];
}
}
const id = recast.types.builders.identifier('prop3');
const value = recast.types.builders.stringLiteral("'a str value'");
const obj_prop = recast.types.builders.objectProperty(id, value);
prop_def.value.properties[0].insertAfter(obj_prop);
break;
}
}
break;
}
}
}
const printed = recast.print(ts_ast).code;
console.log(printed);
Even though the delete
works perfectly, the insertAfter
does not.
I get:
insertAfter is not a function
I've checked and I saw that prop_def
is a Node
and not a NodePath
. It is NodePath
that has the method insertAfter
.
In the README
it says: "Now do whatever you want to ast. Really, anything at all!", but it doesn't say what are the methods to add a new Node
.
Solution 1:[1]
Simplest way to modify AST would be using ?Putout
code transformer, I’m working on.
Here is Replacer
code, it uses ?PutoutScript
:
const from = `
export const theobj:MyType = {
thekey: {
prop1: 5,
prop2: 6
}
}
`
const to = `
export const theobj:MyType = {
thekey: {
prop2: 6,
prop3: 'a str value',
}
}
`
module.exports.replace = () => ({
[from]: to
});
Looks this way:
You can try it in ?Putout Editor
.
It uses recast
and babel
to get things working.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |