-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
fix(eslint-plugin): [no-base-to-string] handle more robustly when multiple toString()
declarations are present for a type
#10432
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
fix(eslint-plugin): [no-base-to-string] handle more robustly when multiple toString()
declarations are present for a type
#10432
Conversation
Thanks for the PR, @kirkwaiblinger! typescript-eslint is a 100% community driven project, and we are incredibly grateful that you are contributing to that community. The core maintainers work on this in their personal time, so please understand that it may not be possible for them to review your work immediately. Thanks again! 🙏 Please, if you or your company is finding typescript-eslint valuable, help us sustain the project by sponsoring it transparently on https://opencollective.com/typescript-eslint. |
✅ Deploy Preview for typescript-eslint ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
☁️ Nx Cloud ReportCI is running/has finished running commands for commit f323fdc. As they complete they will appear below. Click to see the status, the terminal output, and the build insights. 📂 See all runs for this CI Pipeline Execution ✅ Successfully ran 1 targetSent with 💌 from NxCloud. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #10432 +/- ##
==========================================
- Coverage 86.75% 86.75% -0.01%
==========================================
Files 443 443
Lines 15302 15309 +7
Branches 4454 4457 +3
==========================================
+ Hits 13276 13281 +5
- Misses 1672 1673 +1
- Partials 354 355 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
toString()
declarations are present for a type
declare const bb: ExtendedGuildChannel; | ||
bb.toString(); | ||
`, | ||
// https://github.com/typescript-eslint/typescript-eslint/issues/8585 with intersection order reversed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this relevant, you might ask? Because it affects the order in which the overloads are declared (and therefore resolved), at least for TS < 5.4.
type Constructable<Entity> = abstract new (...args: any[]) => Entity;
interface GuildChannel {
toString(): `<#${string}>`;
}
declare const foo: Constructable<GuildChannel & { bar: 1 }>;
class ExtendedGuildChannel extends foo {}
declare const bb: ExtendedGuildChannel;
bb.toString() satisfies `<#${string}>`;
but this errors
(playground)
type Constructable<Entity> = abstract new (...args: any[]) => Entity;
interface GuildChannel {
toString(): `<#${string}>`;
}
declare const foo: Constructable<{ bar: 1 } & GuildChannel>;
class ExtendedGuildChannel extends foo {}
declare const bb: ExtendedGuildChannel;
bb.toString() satisfies `<#${string}>`;
@@ -682,13 +703,63 @@ declare const foo: Bar & Foo; | |||
errors: [ | |||
{ | |||
data: { | |||
certainty: 'will', | |||
certainty: 'may', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just an existing bug of imprecise handling of generics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 😄
24a1510
into
typescript-eslint:main
##### [v8.18.0](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#8180-2024-12-09) ##### 🚀 Features - **eslint-plugin:** \[switch-exhaustiveness-check] add support for "no default" comment ([#10218](typescript-eslint/typescript-eslint#10218)) - **eslint-plugin:** \[no-deprecated] report on super call of deprecated constructor ([#10397](typescript-eslint/typescript-eslint#10397)) ##### 🩹 Fixes - **eslint-plugin:** \[use-unknown-in-catch-callback-variable] only flag function literals ([#10436](typescript-eslint/typescript-eslint#10436)) - **eslint-plugin:** \[no-base-to-string] handle more robustly when multiple `toString()` declarations are present for a type ([#10432](typescript-eslint/typescript-eslint#10432)) - **eslint-plugin:** \[no-deprecated] check if a JSX attribute is deprecated ([#10374](typescript-eslint/typescript-eslint#10374)) - typescript peer dependency ([#10373](typescript-eslint/typescript-eslint#10373)) ##### ❤️ Thank You - Kim Sang Du [@developer-bandi](https://github.com/developer-bandi) - Kirk Waiblinger [@kirkwaiblinger](https://github.com/kirkwaiblinger) - mdm317 - rtritto You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
| datasource | package | from | to | | ---------- | -------------------------------- | ------ | ------ | | npm | @typescript-eslint/eslint-plugin | 8.17.0 | 8.18.0 | | npm | @typescript-eslint/parser | 8.17.0 | 8.18.0 | ## [v8.18.0](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#8180-2024-12-09) ##### 🚀 Features - **eslint-plugin:** \[switch-exhaustiveness-check] add support for "no default" comment ([#10218](typescript-eslint/typescript-eslint#10218)) - **eslint-plugin:** \[no-deprecated] report on super call of deprecated constructor ([#10397](typescript-eslint/typescript-eslint#10397)) ##### 🩹 Fixes - **eslint-plugin:** \[use-unknown-in-catch-callback-variable] only flag function literals ([#10436](typescript-eslint/typescript-eslint#10436)) - **eslint-plugin:** \[no-base-to-string] handle more robustly when multiple `toString()` declarations are present for a type ([#10432](typescript-eslint/typescript-eslint#10432)) - **eslint-plugin:** \[no-deprecated] check if a JSX attribute is deprecated ([#10374](typescript-eslint/typescript-eslint#10374)) - typescript peer dependency ([#10373](typescript-eslint/typescript-eslint#10373)) ##### ❤️ Thank You - Kim Sang Du [@developer-bandi](https://github.com/developer-bandi) - Kirk Waiblinger [@kirkwaiblinger](https://github.com/kirkwaiblinger) - mdm317 - rtritto You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
| datasource | package | from | to | | ---------- | -------------------------------- | ------ | ------ | | npm | @typescript-eslint/eslint-plugin | 8.17.0 | 8.18.0 | | npm | @typescript-eslint/parser | 8.17.0 | 8.18.0 | ## [v8.18.0](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#8180-2024-12-09) ##### 🚀 Features - **eslint-plugin:** \[switch-exhaustiveness-check] add support for "no default" comment ([#10218](typescript-eslint/typescript-eslint#10218)) - **eslint-plugin:** \[no-deprecated] report on super call of deprecated constructor ([#10397](typescript-eslint/typescript-eslint#10397)) ##### 🩹 Fixes - **eslint-plugin:** \[use-unknown-in-catch-callback-variable] only flag function literals ([#10436](typescript-eslint/typescript-eslint#10436)) - **eslint-plugin:** \[no-base-to-string] handle more robustly when multiple `toString()` declarations are present for a type ([#10432](typescript-eslint/typescript-eslint#10432)) - **eslint-plugin:** \[no-deprecated] check if a JSX attribute is deprecated ([#10374](typescript-eslint/typescript-eslint#10374)) - typescript peer dependency ([#10373](typescript-eslint/typescript-eslint#10373)) ##### ❤️ Thank You - Kim Sang Du [@developer-bandi](https://github.com/developer-bandi) - Kirk Waiblinger [@kirkwaiblinger](https://github.com/kirkwaiblinger) - mdm317 - rtritto You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
PR Checklist
⌛ not yet accepting PRs✅Overview
#8585 only repros in TS < 5.4, so you'll want to use the branch playground to verify that the repro in the issue is actually fixed for TS < 5.4.
In short - we want to apply the heuristic that if more than one
toString()
declaration is present for a type, it must be useful. However - there are multiple reasons that multipletoString()
declarations may be present. Therefore, we need to be much more careful about handling intersections and generics, lest we erroneously apply the multiple-declaration heuristic to cases it does not apply.This is all tested for, except, ironically, for the actual repro in the issue, since that requires TS < 5.4, and I don't think we have infra for testing that. Regardless, as said, you can see it working in the branch sandbox