Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: sort-intersection-types conflicts with Prettier on object literal and parenthesized union #407

Open
2 tasks done
JoshuaKGoldberg opened this issue Dec 2, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@JoshuaKGoldberg
Copy link
Contributor

Describe the bug

npx eslint . --fix on the following code autofixes to a layout that Prettier then autofixes right back.

Code example

Original code, as formatted by Prettier, with a lint report on the {\n ... \n}:

type ExtensionlessExportOrImport = (
	| ts.ExportDeclaration
	| ts.ImportDeclaration
) & {
	moduleSpecifier: ts.StringLiteral;
};

Code after perfectionist/sort-intersection-types autofixes it:

type ExtensionlessExportOrImport = {
	moduleSpecifier: ts.StringLiteral;
} & (
	| ts.ExportDeclaration
	| ts.ImportDeclaration
);

Code after formatting with Prettier:

type ExtensionlessExportOrImport = {
	moduleSpecifier: ts.StringLiteral;
} & (ts.ExportDeclaration | ts.ImportDeclaration);
//   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// eslint(perfectionist/sort-intersection-types)
// Expected "ts.ExportDeclaration | ts.ImportDeclaration" to come before "{ moduleSpecifier: ts.StringLiteral;

ESLint version

9.16.0

ESLint Plugin Perfectionist version

4.1.2

Additional comments

Not sure if the bug is here or in Prettier... 🤔

Validations

  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
@JoshuaKGoldberg JoshuaKGoldberg added the bug Something isn't working label Dec 2, 2024
@hugop95
Copy link
Contributor

hugop95 commented Dec 2, 2024

Hi @JoshuaKGoldberg 👋

Could you write the .prettierrc + perfectionist options that you use?

@JoshuaKGoldberg
Copy link
Contributor Author

D'oh, sorry! I got so used to quickly reporting issues I forgot to respect the checklist. 🙈

Full repro here: https://github.com/JoshuaKGoldberg/repros/tree/repro-perfectionist-sort-intersection-types-conflict-prettier

import js from "@eslint/js";
import perfectionist from "eslint-plugin-perfectionist";
import tseslint from "typescript-eslint";

export default tseslint.config(
  js.configs.recommended,
  tseslint.configs.recommended,
  perfectionist.configs["recommended-natural"],
);

Prettier is set with defaults.

@hugop95
Copy link
Contributor

hugop95 commented Dec 2, 2024

@JoshuaKGoldberg Thank you! The issue comes from how we compute names to compare:

in

type ExtensionlessExportOrImport = {
	moduleSpecifier: ts.StringLiteral;
} & (
	| ts.ExportDeclaration
	| ts.ImportDeclaration
);

one node will have |ts.exportdeclaration|ts.importdeclaration for comparison value, and in

type ExtensionlessExportOrImport = {
	moduleSpecifier: ts.StringLiteral;
} & (ts.ExportDeclaration | ts.ImportDeclaration);

it will have ts.ExportDeclaration|ts.ImportDeclaration (notice the missing | at the start).

Not sure if the bug is here or in Prettier... 🤔

Technically speaking, prettier is adding/removing | at the start, so we could say that they are the ones starting the hostilities 😇

The quick-fix you can do on your end is setting the specialCharacters option to trim.

Users should ideally not have to do that to have a working configuration, though, so we can try to provide a fix as well, but I'm not sure if we can do that without potentially breaking the current sort order of users.

@hirotomoyamada
Copy link

@hugop95

Hi, we set "trim" to specialCharacters and that solved the problem! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants