dsherret / dsherret/ts-morph

fixMissingImports after removing import raised ManipulationError

Open
#1,342 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
6.2k
Forks
238
Avg merge
2m
Merged PRs (30d)
1

Description

**Describe the bug**
I want to remove some invalid imports caused by code move and reimport from the new correct modules. Removing imports and fixMissingImports both works itself but combining them together would raise manipulation error in the following case.

Error:
Manipulation error: Error replacing tree: The children of the old and new trees were expected to have the same count (2:4).
![image](https://user-images.githubusercontent.com/10512841/196725426-01ad9dda-09f1-45c2-9ff7-fc22ff20634d.png)

Version: 12.2.0

**To Reproduce**

```ts
import { Project } from "ts-morph";

const project = new Project();
project.createSourceFile(
"service.ts",
`
export const a = 100;
`
);
project.createSourceFile(
"service.interface.ts",
`
export interface IA {}

export class ClassB {
public errorCode: string;
}
`
);
project.createSourceFile(
"service.mock.ts",
`
import {
IA,
} from "./service.interface";
import { ClassB } from "./service";

export class ClassC extends ClassB {}
export class ClassA implements IA {}
`
);

const queue = [];
project.getSourceFiles().forEach((sourceFile) => {
return sourceFile.getImportDeclarations().forEach((declaration) => {
declaration.getNamedImports().forEach((namedImport) => {
if (!declaration.getModuleSpecifierValue().startsWith(".")) {
return;
}
const sourceFileImported = declaration.getModuleSpecifierSourceFile();
if (
sourceFileImported === undefined ||
!hasNamedExport(sourceFileImported, namedImport.getName())
) {
queue.push(() => {
namedImport.remove();
if (declaration.getNamedImports().length === 0) {
declaration.remove();
}
declaration.getSourceFile().fixMissingImports();
return declaration.getSourceFile().getFilePath();
});
}
});
});
});

const optimizedFiles = queue.map((fn) => fn());
project.saveSync();

console.log(optimizedFiles.join("\n"));

function hasNamedExport(sourceFile, namedExport: string): boolean {
return [...sourceFile.getExportedDeclarations().keys()].some(
(name: string) => name === namedExport
);
}

```

**Expected behavior**

It should work the same as I execute remove imports and fixMissingImports separately.

Contributor guide

Open the contributing guide

Research direction

Read CONTRIBUTING.md, then run the provided TypeScript reproduction against version 12.2.0, focusing on the queued named-import removal followed by fixMissingImports(). Compare the combined operation with performing those operations separately. Done means the reproduction completes without a ManipulationError and the resulting imports match the expected behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.