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

When transform nullish coalescing it transform != null which may lead to wrong result #3772

Closed
IrisChen7 opened this issue May 17, 2024 · 3 comments

Comments

@IrisChen7
Copy link

IrisChen7 commented May 17, 2024

esbuild version: esbuild
node version: 16.20.0

Below is my code

import * as esbuild from 'esbuild'

let ts = 'a = b ?? 1'
let result = await esbuild.transform(ts, {
  target: [
    'es6',
  ],
})
console.log(result.code)

Run result:
a = b != null ? b : 1;

Expected result:
a = b !== null && a !== undefined ? b : 1;

Since result of 0 ?? 1 is 0, this may lead to wrong result, is there any settings that can make it right?

@IrisChen7 IrisChen7 changed the title When transform nullish coalescing it transform != null When transform nullish coalescing it transform != null which may lead to wrong result May 17, 2024
@hyrious
Copy link

hyrious commented May 17, 2024

a == null is effectively equal to a === null || a === undefined, as the spec of ECMAScript said. So it is a totally correct transform.

$ node -p 'a=0;b=1;a??b'
0

$ node -p 'a=0;b=1;a!=null?a:b'
0

@magic-akari
Copy link
Contributor

The only difference is document.all.
If you are using Babel, you can achieve code as concise as esbuild's by set https://babeljs.io/docs/assumptions#nodocumentall.

Apart from document.all, they are equivalent.

It appears that esbuild has adopted this strategy by default.

@evanw
Copy link
Owner

evanw commented May 17, 2024

Yes, the document.all edge case is only the reason why some tools have different output than esbuild here. Specifically document.all is the only value in all of JavaScript for which x != null is false but x !== null && x !== undefined is true.

But it's such an obscure edge case that I have decided I don't care about it. FWIW terser, another popular JavaScript minifier, has also decided that they don't care about document.all either: terser/terser#408.

It's ancient web history and doesn't belong in modern JavaScript code. It's not worth bloating everyone's code by transforming ?? into this double-comparison just to handle the document.all value that no one should be using in the first place.

I'm closing this issue as I won't be changing anything here.

Since result of 0 ?? 1 is 0, this may lead to wrong result, is there any settings that can make it right?

Note that 0 ?? 1 and 0 != null ? 0 : 1 are both 0. So esbuild is correct.

@evanw evanw closed this as not planned Won't fix, can't repro, duplicate, stale May 17, 2024
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

4 participants