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
feat(eslint-plugin): [no-unsafe-assignment] [no-unsafe-return] add never support #2746
Conversation
Thanks for the PR, @CreativeTechGuy! 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. |
Codecov Report
@@ Coverage Diff @@
## master #2746 +/- ##
=======================================
Coverage 92.79% 92.80%
=======================================
Files 297 297
Lines 9833 9845 +12
Branches 2762 2769 +7
=======================================
+ Hits 9125 9137 +12
Misses 332 332
Partials 376 376
Flags with carried forward coverage won't be shown. Click here to find out more.
|
After implementing this and trying it out I feel this is the wrong way to go about handling I'm going back to the drawing board with a |
This check is too expensive to realistically do. This is why the
Whilst
Ultimately users can enable them all at once by turning on our Additionally - something you may have overlooked is the generic safety checks that these rules do on top of simple checks. These rules check things like Example of how declare function foo<T = never>(arg?: T): Set<T>;
const x = foo(); // x === Set<never>
const y = foo('a'); // y === Set<string>
function test(): Set<string> {
return x; // returning Set<never> into a Set<string> is super unsafe but it's "compile-time safe"!
}
// Example of where things get really unsafe:
function addToStringSet(arg: Set<string>) {
arg.add('foo');
}
function addToNumberSet(arg: Set<number>) {
arg.add(1);
}
addToStringSet(x);
addToNumberSet(x);
// x is still of type Set<never>
// but it === new Set(['foo', 1]);
// it's assignable to any set - i.e. SUPER unsafe |
I clearly don't understand the considerations that go into an ESLint rule like I had thought. I'm glad you are here to check my misconceptions. There's a lot of things which I've never encountered in practice and so I never considered. I'll close this PR to not clutter up the list as I don't think I'd be able to build a rule to the quality required. Thanks again for all of your great explanations. I learned a lot. A suggestion for the future: Could there be performance profiling tests for each rule? It'd be great both as a user to see how much enabling each rule would cost and also as a developer so I could have more easily caught the fact that my rule was going to not meet the performance threshold. (I'll create a separate Issue for this suggestion so it can be tracked.) |
#2616
This PR adds support for
never
as an unsafe assignment and an unsafe return. It was added as an extension to these existing rules per @bradzacher 's suggestion in this comment.I do want to call out that I didn't want to copy every existing test and change
any
->never
so the tests I added were carefully chosen to highlight the key feature of addingnever
support (where applicable). I can see these rules being expanded in the future (maybe if the TypeScript language adds some new types) and don't want to make these rules too reliant on a specific type that it's checking for.As mentioned in the comment linked above, these two rule updates are only part of the larger feature to warn against
never
in all cases. There is still an issue of passingnever
to a function but the appropriate ruleno-unsafe-argument
has not yet been created.