-
Notifications
You must be signed in to change notification settings - Fork 64
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
Disallowing non-null assertions using the !
postfix operator disregards its validity in the majority of code-bases
#422
Comments
I managed to get this working by not using standard or standard js, but by manually installing the rule set and using a |
I'm curious to know how often this actually comes up in your projects 🤔 In my team we love having this rule since it avoids some very hard to track down bugs where null/undefined have propagated quite far from the actual We are using a combination of What I like about having to use "eslint-disable" for these cases is that it signals that "hey, TypeScript cannot guarantee that this code works, so we have to be extra careful here" to the developers. Just my 2 cents, would love to hear more about your use cases... |
While I cannot talk for the community at large, the I have also worked with flow codebases that uses the equivalent of So basically, even though you can add runtime checks all over the code, it is not a panacea, simply telling the type checker to shut up is sometimes what you want |
I'm against this rule, let the compiler do its job, and warns you if you do mistakes. const arr = sortNumbers(2, 5, 7, 3, 1, 8, 10)
let smallest = arr[0]
const shift = arr.shift()!
smallest = shift Check yourself if const shift = arr.shift()
if (shift == null) {
throw new Armageddon('For may the Lord have mercy on our souls')
}
smallest = shift It adds a little bit of code, but it is way safer than using For example : const arr = sortNumbers()
let smallest = arr[0]
const shift = arr.shift()!
smallest = shift This code would compile, but you would get |
@rostislav-simonik and I looked at this. Here is our summary. In the vast majority of cases where a value may be nullish, type guards should be used. In the expectional cases where a non-null assertion is appropriate, do use one and place an By the way, type guards in TypeScript have improved since the opening of this issue, if that matters. With this we are closing this issue. Feel free to try to change our minds. |
What version of this package are you using?
"version": "19.0.1",
What operating system, Node.js, and npm version?
node-v14.9.0
npm-7.0.0-beta.9
macOS Catalina-v10.15.6
Summary
The postfix operator has the very valid usecase of making the type system behave reasonably in places where it can't grasp the causality of an operation. This restriction specifically affects arrays and maps in their most basic functionaly. There is no alternative of reasonalble terseness, so the existing alternatives cause clutter that is completly unnecessary in terms of type-safety.
Array and Maps are so common that this rule affect an enormous amount of code while forbidding the use of the
!
postfix operator will only catch very few things that could lead to actual runtime issues.While there are other things that are negatively affected by this, The specific ones stated here is more than enough to make this rule unusable across the majority of common code-bases.
Current Rule Definition
Suggested Change
Examples of the type system including
undefined
where it is causally impossibleMaps and their most basic functionality
Given a function mapping object
k/v
pairs to a ReadonlyMapWe know the exact state of the returned Map and it is declared as immutable, but the type system isn't aware of the consequences.
Arrays and their most basic functionality
Given a function that sorts any amount of number and returns them in an array
We know that there is guarantied to be a number at the first position, and accessing it via indexing does confirm that again. Never the less typescript will throw a compiler error if we want to assign the return value of the first call to
Array.prototype.shift
totypeof arr[0]
Probably the most common way of checking wether an array is empty of not is checking wether its
length
is 0 or falsy, nut the type system doesn't understand that causality.Comparing the
!
postfix operator to the available alternativesWe use the same functions as above
Using the
!
postfix operatorThe resulting source code is very clean. The addition of the operator doesn't plaster the code with extra information, type infernce reflects runtime behaviour, and the operators are transpiled a way at compile time.
Maps
Arrays
Using conditionals
The resulting source AND production code include a large amount of redundant operations, the code might appear a bit odd at first, but it is readable.
Maps
Arrays
Using type assertions
The resulting source code grows a considerable amount as we need explicitly write the type logic which was inferred in the other examples before we can cast it. And not all of it is stripped at compile time if we use the more practical approach and use what inferrence we can instead of typing everything manually. Either way, as a result the source becomes a lot less consumable for readers and mentainers because of all the declarations are (wether real or type) have to be kept in mind to avoid naming conflicts. much of the necessary logic also has to use conditional types which can get very large very fast. All of this is also much more error prone compared to pure inference. (i infact had to correct this section multiple times)
Maps
Arrays
The text was updated successfully, but these errors were encountered: