ts-morph
ts-morph copied to clipboard
[Question] Idiomatic way to insert before the return statement of a function?
Hi,
Thanks for this project. I'm trying a simple automatic implementation à la Rust macros. I have a crude POC that is almost working:
//- find all createXXXStore methods
project.getSourceFiles().forEach((sourceFile) => {
const func: FunctionDeclaration | undefined = sourceFile.getFunction((f) => {
const func_name = f.getName();
if (func_name) {
const low = func_name.toLowerCase();
return low.startsWith("create") && low.endsWith("store");
}
return false;
});
if (!func) return;
//- extract the store type from the first parameter
const initial_type = func.getParameters()[0];
const props = initial_type.getType().getProperties();
//- from each properties of our type we extract information to create setters.
props.forEach((p) => {
const name = p.getName();
const kind = p.getTypeAtLocation(initial_type);
//- naive way to get the location before the return block
const child_location = func.getChildCount() - 1;
//- make our setter
const setter = func.insertFunction(child_location, {
name: toCamelCase("set-" + name),
leadingTrivia: "// autogenerated with ts-morph",
statements: `update((state) => {
return {
...state,
${name},
};
});`,
parameters: [
{
name: name,
type: kind.getText(),
},
],
});
});
console.log(sourceFile.print({}));
});
TLDR
func.getChildCount() in the above code does not return the proper value: InvalidOperationError: Invalid index: The max index is 4, but 5 was specified. so childCount returned 6 instead of the 4 children the method has