prettier-plugin-sort-imports icon indicating copy to clipboard operation
prettier-plugin-sort-imports copied to clipboard

Type reordering `import { type SomeType }` moves top-of-file comment below imports

Open max-m opened this issue 11 months ago • 3 comments

Your Environment

  • Prettier version: 3.4.2
  • node version: 21.7.1
  • package manager: npm@10

Describe the bug

When type reordering is active and a file has import { type SomeType }-imports, the top-of-file comment gets moved around. When the type imports are sorted, the top-of-file comment stays put.

To Reproduce

test.ts:

/*
 * Copyright (c) 1234-5678 Some one.
 *
 * This is my top-of-file comment
 */

import SomeThing, { type SomeType } from '../SomeModule'
import Function from '../Functions'
import * as SomeUtil from 'Some/Other/Module'

import type Foo from '../Foo'

gets formatted as

import type Foo from '../Foo'
import type { SomeType } from '../SomeModule'

import * as SomeUtil from 'Some/Other/Module'

import Function from '../Functions'
import SomeThing from '../SomeModule'

/*
 * Copyright (c) 1234-5678 Some one.
 *
 * This is my top-of-file comment
 */


test2.ts

/*
 * Copyright (c) 1234-5678 Some one.
 *
 * This is my top-of-file comment
 */

import SomeThing from '../SomeModule'
import Function from '../Functions'
import * as SomeUtil from 'Some/Other/Module'

import type { SomeType } from '../SomeModule'
import type Foo from '../Foo'

becomes

/*
 * Copyright (c) 1234-5678 Some one.
 *
 * This is my top-of-file comment
 */

import type Foo from '../Foo'
import type { SomeType } from '../SomeModule'

import * as SomeUtil from 'Some/Other/Module'

import Function from '../Functions'
import SomeThing from '../SomeModule'

test3.ts:

/*
 * Copyright (c) 1234-5678 Some one.
 *
 * This is my top-of-file comment
 */

import SomeThing from '../SomeModule'
import Function from '../Functions'
import * as SomeUtil from 'Some/Other/Module'

import { type SomeType } from '../SomeModule'
import type Foo from '../Foo'

becomes

import type Foo from '../Foo'
import type { SomeType } from '../SomeModule'

import * as SomeUtil from 'Some/Other/Module'

import Function from '../Functions'
import SomeThing from '../SomeModule'

/*
 * Copyright (c) 1234-5678 Some one.
 *
 * This is my top-of-file comment
 */

Expected behavior

I expected the top-of-file comment to stay put in all cases.

.prettierrc:

semi: false
singleQuote: true
useTabs: true
trailingComma: all
printWidth: 120

plugins: ["@ianvs/prettier-plugin-sort-imports"]

importOrder:
  - "" # Enforce a blank line after top of file comments
  - "<TYPES>"
  - "" # Seperator
  - "<THIRD_PARTY_MODULES>"
  - "" # Separator
  - "^[.]"
importOrderParserPlugins: ["typescript", "decorators"]
importOrderTypeScriptVersion: '5.7.3'

Error log

Contribute to @ianvs/prettier-plugin-sort-imports

  • [ ] I'm willing to fix this bug 🥇

max-m avatar Feb 07 '25 03:02 max-m

That’s super weird: we have a test-case for this use-case!

https://github.com/IanVS/prettier-plugin-sort-imports/blob/main/tests/InjectBlankLineAfterTopOfFileComments/imports-with-file-level-comments.ts

fbartho avatar Feb 07 '25 06:02 fbartho

@fbartho it sounds like this only happens when sorting types, which that test case doesn't address. Sounds like we'll need to do some investigating. Thanks for the report, @max-m.

IanVS avatar Feb 07 '25 14:02 IanVS

Looks like it’s more specific @IanVS — it’s not just sorting types, it’s when “unpacking” a combined “type and normal” import into separated types and normal sections.

I don’t use this case, but I bet the unpacking migration is where a missing piece of logic lives.

Any statements that aren’t present in the import-node tree after our sort operation fall to the bottom of all imports. In the case of “splitting” an import statement into two, the old import node is deleted, and the comment statement maybe attached to that import, so it’s considered forgotten, which is treated as if it’s a line of code in the file.

fbartho avatar Feb 07 '25 19:02 fbartho