-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
fix(eslint-plugin): [non-nullable-type-assertion-style] fix false positive when asserting to a generic type that might be nullish #4509
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
Conversation
… when casting to a type parameter that might be nullish
Thanks for the PR, @djcsdy! 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. As a thank you, your profile/company logo will be added to our main README which receives thousands of unique visitors per day. |
✔️ Deploy Preview for typescript-eslint ready! 🔨 Explore the source changes: da49d03 🔍 Inspect the deploy log: https://app.netlify.com/sites/typescript-eslint/deploys/61fda4d5498aac00075a7890 😎 Browse the preview: https://deploy-preview-4509--typescript-eslint.netlify.app |
Codecov Report
@@ Coverage Diff @@
## main #4509 +/- ##
==========================================
+ Coverage 92.49% 94.57% +2.08%
==========================================
Files 346 147 -199
Lines 11684 7888 -3796
Branches 3335 2534 -801
==========================================
- Hits 10807 7460 -3347
+ Misses 608 234 -374
+ Partials 269 194 -75
Flags with carried forward coverage won't be shown. Click here to find out more. |
👋 @djcsdy thanks for finding this bug and sending a PR! Much appreciated on the initiative! ❤️ As hinted by the PR template you used, we ask that all PRs address an existing issue. Would you be able to file an issue for this please? I'll still give the PR a review but if we end up discussing in more depth then that should be in an issue. For the room: this gives bug reports more visibility and lets us comment on them before someone starts work on them. We'd want to confirm an issue is valid (this one certainly is) and what the right fix might be if it's not clear. Soon/eventually I/we/someone will write a GitHub bot to enforce it... Side note: I re-opened #4010 and sent #4511 to make the PR template a little more clear. |
{ | ||
"extends": "./tsconfig.json", | ||
"compilerOptions": { | ||
"noUncheckedIndexedAccess": true |
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.
Really nice find here. I shudder to think what other subtle edge cases have popped up because of that 😄
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.
fwiw this issue can arise even without noUncheckedIndexAccess
, but off the top of my head I can't think of an example that isn't totally contrived :-).
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.
Oh? I was playing around with this for a good bit to try to find one but couldn't find anything. Is there a code snippet you have in mind?
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.
I couldn't find one either to be honest, but I didn't try all that hard. Maybe it really is dependent on the flag. But even if it isn't I think this fix should suffice. I'll do some experimentation.
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.
Generally looks good to me! And thank you for the detailed description; it greatly helped me -as someone who doesn't use noUncheckedIndexedAccess
much- read what's going on. 😄
Just requesting changes on more testing coverage and deep union type checking. Filing an issue would be nice but I don't want to block this good PR on it -- if you don't have time I can.
packages/eslint-plugin/tests/rules/non-nullable-type-assertion-style.test.ts
Show resolved
Hide resolved
…`string | undefined` and `string | null | undefined`
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.
Wonderful, thanks @djcsdy! This is great. 🔥
I'll go ahead and merge this now because this is a good fix (and the typo hurts me, heh). But if you do have another example -even contrived- please do post back and we can work on that too!
…itive when asserting to a generic type that might be nullish (typescript-eslint#4509)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint) | devDependencies | minor | [`5.10.2` -> `5.12.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2feslint-plugin/5.10.2/5.12.0) | | [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint) | devDependencies | minor | [`5.10.2` -> `5.12.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/5.10.2/5.12.0) | --- ### Release Notes <details> <summary>typescript-eslint/typescript-eslint (@​typescript-eslint/eslint-plugin)</summary> ### [`v5.12.0`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#​5120-httpsgithubcomtypescript-eslinttypescript-eslintcomparev5110v5120-2022-02-14) [Compare Source](typescript-eslint/typescript-eslint@v5.11.0...v5.12.0) ##### Bug Fixes - **eslint-plugin:** \[init-declarations] fix nested namespace ([#​4544](typescript-eslint/typescript-eslint#4544)) ([fe910e6](typescript-eslint/typescript-eslint@fe910e6)) - **eslint-plugin:** \[no-unnecessary-type-arguments] Use Symbol to check if it's the same type ([#​4543](typescript-eslint/typescript-eslint#4543)) ([5b7d8df](typescript-eslint/typescript-eslint@5b7d8df)) - support nested object deconstructuring with type annotation ([#​4548](typescript-eslint/typescript-eslint#4548)) ([4da9278](typescript-eslint/typescript-eslint@4da9278)) ##### Features - add checking property definition for allowNames option ([#​4542](typescript-eslint/typescript-eslint#4542)) ([e32bef6](typescript-eslint/typescript-eslint@e32bef6)) ### [`v5.11.0`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#​5110-httpsgithubcomtypescript-eslinttypescript-eslintcomparev5102v5110-2022-02-07) [Compare Source](typescript-eslint/typescript-eslint@v5.10.2...v5.11.0) ##### Bug Fixes - **eslint-plugin:** \[no-magic-numbers] fix invalid schema merging ([#​4517](typescript-eslint/typescript-eslint#4517)) ([b95f796](typescript-eslint/typescript-eslint@b95f796)) - **eslint-plugin:** \[non-nullable-type-assertion-style] fix false positive when asserting to a generic type that might be nullish ([#​4509](typescript-eslint/typescript-eslint#4509)) ([4209362](typescript-eslint/typescript-eslint@4209362)) ##### Features - **eslint-plugin:** \[explicit-function-return-type] add allowedNames ([#​4440](typescript-eslint/typescript-eslint#4440)) ([936e252](typescript-eslint/typescript-eslint@936e252)) #### [5.10.2](typescript-eslint/typescript-eslint@v5.10.1...v5.10.2) (2022-01-31) ##### Bug Fixes - **eslint-plugin:** \[no-restricted-imports] allow relative type imports with patterns configured ([#​4494](typescript-eslint/typescript-eslint#4494)) ([4a6d217](typescript-eslint/typescript-eslint@4a6d217)) #### [5.10.1](typescript-eslint/typescript-eslint@v5.10.0...v5.10.1) (2022-01-24) **Note:** Version bump only for package [@​typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/eslint-plugin) </details> <details> <summary>typescript-eslint/typescript-eslint (@​typescript-eslint/parser)</summary> ### [`v5.12.0`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#​5120-httpsgithubcomtypescript-eslinttypescript-eslintcomparev5110v5120-2022-02-14) [Compare Source](typescript-eslint/typescript-eslint@v5.11.0...v5.12.0) **Note:** Version bump only for package [@​typescript-eslint/parser](https://github.com/typescript-eslint/parser) ### [`v5.11.0`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#​5110-httpsgithubcomtypescript-eslinttypescript-eslintcomparev5102v5110-2022-02-07) [Compare Source](typescript-eslint/typescript-eslint@v5.10.2...v5.11.0) **Note:** Version bump only for package [@​typescript-eslint/parser](https://github.com/typescript-eslint/parser) #### [5.10.2](typescript-eslint/typescript-eslint@v5.10.1...v5.10.2) (2022-01-31) **Note:** Version bump only for package [@​typescript-eslint/parser](https://github.com/typescript-eslint/parser) #### [5.10.1](typescript-eslint/typescript-eslint@v5.10.0...v5.10.1) (2022-01-24) **Note:** Version bump only for package [@​typescript-eslint/parser](https://github.com/typescript-eslint/parser) </details> --- ### Configuration 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Renovate will not automatically rebase this PR, because other commits have been found. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox. --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Co-authored-by: cabr2-bot <cabr2.help@gmail.com> Co-authored-by: crapStone <crapstone@noreply.codeberg.org> Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1157 Reviewed-by: crapStone <crapstone@noreply.codeberg.org> Co-authored-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org> Co-committed-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
PR Checklist
Overview
Consider the following code:
When compiling with
noUncheckedIndexedAccess
, the type assertionarray[0] as T
is required because the original type ofarray[0]
isT | undefined
.However, non-nullable-type-assertion-style complains about the cast, suggesting that it should be
array[0]!
instead. This is not correct because the type parameterT
might itself be nullish.array[0]!
is equivalent toarray[0] as NonNullable<T>
, which is not the same asarray[0] as T
.To see the issue more clearly, consider the following slightly more contrived example:
non-nullable-type-assertion-style complains about this code too, but here the problem is more obvious. Clearly the type assertion
array[0] as T
is not equivalent toarray[0]!
because the type parameterT
has a constraint that explicitly allows the type to benull
.This PR loosens non-nullable-type-assertion-style so that in addition to the type assertions it already allows, it will also allow type assertions providing both of the following conditions are true: