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

Allow loose equal for null comparison #72

Closed
hpohlmeyer opened this issue Oct 22, 2019 · 3 comments
Closed

Allow loose equal for null comparison #72

hpohlmeyer opened this issue Oct 22, 2019 · 3 comments

Comments

@hpohlmeyer
Copy link
Member

Checking for null or undefined can be really verbose. Especially if we have some optional chaining. A recent example:

if (
  result !== undefined &&
  result !== null &&
  result.data !== undefined &&
  result.data !== null
) { ... }

with optional chaining this becomes easier:

if (result?.data !== undefined && result?.data !== null) { ... }

but it is still pretty verbose. I am not in favor of allowing losse equality everywhere, but since the eqeqeq rule has a smart rule for exactly that case I would like to discuss it here.

The example from above would look like this then:

// without optional chaining
if (result.data != null && result.data != null) { ... }

// with optional chaining
if (result?.data != null) { ... }

What do you think?

@jhnns
Copy link
Member

jhnns commented Jan 22, 2020

I agree, checking for null and undefined is cumbersome and I don't want the linting rules to be annoying.

However, there are three reasons why I'm hesitant to add this:

  • If it's your own code, you should pick null or undefined. If your team uses both, the code becomes unnecessarily complex. See also null vs undefined #71.
  • document.all == null returns true (see this SO answer). This is the reason why JS engines can't properly optimized == null checks because they have to perform a heap lookup in order to compare against document.all
  • == null is unnecessarily clever in my opinion. You have to actually learn this fact that undefined == null which is not obvious for beginners.

Is there a popular library that mixes both null and undefined? In that case I would understand why people want to use the == null check. We could also add it as separate style (#24) so that you can activate this if you really need it.

What do you think? :)

@hpohlmeyer
Copy link
Member Author

you should pick null or undefined.

Good point! We currently run into that case with the graphql-codegen. Here is an excerpt of the code on the landing page of the project:

Schema

type Query {
  me: User!
  user(id: ID!): User
  allUsers: [User]
  search(term: String!): [SearchResult!]!
  myChats: [Chat!]!
}

Generated output

export type Query = {
   __typename?: 'Query',
  me: User,
  user?: Maybe<User>,
  allUsers?: Maybe<Array<Maybe<User>>>,
  search: Array<SearchResult>,
  myChats: Array<Chat>,
};

Maybe is defined as type Maybe<T> = T | null, which in this case means that the user property has a type of User | undefined | null, which makes it mandatory to check for undefined and null whenever you want to use it.


document.all == null returns true […] This is the reason why JS engines can't properly optimized == null checks

I did not know that. That sucks big time :/. So we might still be better of with a helper function that checks for both undefined and null, if we need such checks frequently.


== null is unnecessarily clever in my opinion

I think you are right with this, especially since it is hard to spot the missing equal, if you are used to see tripple equals everywhere else. But once you get used to reading it, it can improve readability since you do not need to mentally skip every second line.

Here is an example from a recent code review:

if (
  creditcardNumber != null &&
  creditCardAccountholder != null &&
  expirationDate != null
) {  }

// vs

if (
  creditcardNumber !== null &&
  creditcardNumber !== undefined &&
  creditCardAccountholder !== null &&
  creditCardAccountholder !== undefined &&
  expirationDate !== null
  expirationDate !== undefined
) {  }

We could also add it as separate style (#24) so that you can activate this if you really need it.

I am not so sure about this anymore. The inability to optimize it properly and the learning curve for beginners throw me off. For both cases it might be superior to have a helper function to deal with this stuff. I’ll close the issue for now.

@jhnns
Copy link
Member

jhnns commented Feb 1, 2020

In an effort to make these rules less annoying for most people I decided to allow this kind of pattern (although I personally dislike it :))

jhnns added a commit that referenced this issue Feb 1, 2020
It's quite common for developers to use loose comparison to compare against null. Although this pattern is perceived as problematic by some developers, it can be quite useful in other situations. The validity of this comparison should be checked during code review.

See #72
jhnns added a commit that referenced this issue Mar 23, 2020
Relaxing eqeqeq was not enough (e8f9cd6), we also need to disable this rule.

See also #72
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants