A new conditioning way, compare multiple right hand values.

Hi fellows,
Many times I have experienced the case where I have to check the same variable for different values, and when the variable is long, it gets awkward and the code does not look well.

For example:

if(objectWithVeryLongName.itemWithVeryLongName == 1 || objectWithVeryLongName.itemWithVeryLongName == 2 || objectWithVeryLongName.itemWithVeryLongName == 3) ....

I usually do something like:

if([1,2,3].includes(objectWithVeryLongName.itemWithVeryLongName)) .... 

but is a bit hacky, and also I can't get advantage from the type comparing (==, ===). Sometimes maybe I'll want to check for string or number to be present in the variable, in this case I'll have to go even hackyer. And yes, I know I can use [test] regexp... still hacky!

I want this:

if(objectWithVeryLongName.itemWithVeryLongName == (1 || 2 || 3)) ....

This is what the console shows (for the people that claim that this is working in JS), it is not throwing error but gets only the first value under consideration.

1 == (1 || 2 || 3) // true
2 == (1 || 2 || 3) // false
3 == (1 || 2 || 3) // false

Thank you for your attention :)

That particular syntax is already valid and can't be changed.

https://github.com/tc39/proposal-pattern-matching may be a good solution for this.

1 Like

Some other threads:

if([1,2,3].includes(objectWithVeryLongName.itemWithVeryLongName)) ....

I don't find this to be hacky at all, in fact I'd encourage the use of that pattern, I find it to be very readable.

It's unfortunate that Typescript doesn't handle Inference very well when you use that pattern, but that's a Typescript problem, not a JavaScript one. There have been attempts to ask for something like this, but the response is basically "it would require adding support for a new way to describe a type to make this work, and at this time they don't feel it's worth implementing it, partly due to the complexity cost it would put on the Typescript codebase" (see the end of .includes or .indexOf does not narrow the type · Issue #36275 · microsoft/TypeScript · GitHub)

1 Like

Yeah, I know it's a good pattern, this is what I am using.... because there is no what I want. And if to create array and use includes() function to have checked 2~3 value is not hacky, I don't know, then what is it :blush:

The problem is not Typescript, my problem is that I can't use == equality, this way is capable only of strict equality check. You maybe never experience the need of something like this, but I have many times, and it gets even hackyer when you have to cast everything to numbers, for example.


I'm confused; .includes() is already using SameValueZero semantics (===); what other comparisons are you trying to do?

I can't use == equality, this way is capable only of strict equality check (===), this works only if you are sure of the incoming data types, or we need to cast them to String or Number.

ah, well sure, but coercing them to the proper types, or validating their types, is a good thing to do anyways.

1 Like

That's why if I need the correct types I'll use ===, besides what I propose is not something eccentric and overengineered, it looks very JS style :) right?

There is time and case for everything, checking types of the variables is not necessarily a good thing. If this was JAVA, I'm gonna be sure that my incoming data is expected type, but this is JAVASCRIPT and its freedom is what makes it so powerful!

Certainly this is subjective, but I indeed think that checking the types of the variables every single code path, without exception is indeed necessary and a good thing. Using == is not very JavaScripty any more, because such looseness has not been encouraged or idiomatic for a long, long time.

Ok, I see you know yours, and you are trying to convince everybody that you are the right :)

Let's forget for a moment about this type check, I suppose this is a matter of personal opinion, you say it is bad, I say it's good. The truth is, this functionality exists and will never disappear from JS, and it's here to stay no matter you approve it or not.

Let's go back to the fact where creating array and use includes() function is a total hack, any further comment there?

Nope, like other commenters, that seems perfectly reasonable to me. Pattern matching will certainly be a better choice in a future where it's available.

@ljharb Could you please post some example code that solves this problem with your preferred way?


if(objectWithVeryLongName.itemWithVeryLongName == 1
  || objectWithVeryLongName.itemWithVeryLongName == 2 
  || objectWithVeryLongName.itemWithVeryLongName == 3){



Thank you!

I think any of these are viable:

if (
objectWithVeryLongName.itemWithVeryLongName == 1
>> objectWithVeryLongName.itemWithVeryLongName == 2
>> objectWithVeryLongName.itemWithVeryLongName == 3
) {
const values = new Set([1, 2, 3]);
if (values.has(objectWithVeryLongName.itemWithVeryLongName)) {
const values = [1, 2, 3];
if (values.includes(objectWithVeryLongName.itemWithVeryLongName)) {
if ([1, 2, 3].includes(objectWithVeryLongName.itemWithVeryLongName)) {

with proposed pattern matching syntax:

if (objectWithVeryLongName.itemWithVeryLongName is 1 or 2 or 3) {

For the first 4 methods, I have no comments, you know why.
For the last one, not too bad... but still, how this syntax

if (objectWithVeryLongName.itemWithVeryLongName is 1 or 2 or 3) {

is more JS looking than this one

if (objectWithVeryLongName.itemWithVeryLongName === 1 || 2 || 3) {

where in JS has (is, or), and I bet it's checking the types as well, which is half of my problem.

And lastly, your method is replaceable with 4 other currently available approaches, you just wrote them above, my suggestion from the other hand, handles one more problem that none of the 4 is able to handle ( ignore types checking :smile:).

Don't get me wrong, I have no desire to be right and my suggestion comes from my needs. Honestly, if you add one more argument to includes() that ignore the types, we can shake our hands as well.

something like:
if([1,2,3].includes(objectWithVeryLongName.itemWithVeryLongName, true)) {

That would be encouraging implicit coercion, which the community at large as well as the committee itself has been moving away from quite intentionally.

Honestly, if you add one more argument to includes() that ignore the types, we can shake our hands as well.

Isn't that just as much trouble as doing explicit coercion?

E.g. say you have a variable "value" that could be a number or a string. And you want to check if it's equal to a handful of different strings. You could just do this:

['1', '2', '3'].includes(String(value))

Which would solve the same use-case as using a hypothetical API that auto-coerces

['1', '2', '3'].includes(value, { coerce: true })

That wouldn't work if your search set has multiple types

['1', 2, '3'].includes(String(value))

You could use some() which would let you be explicit about how you compare

['1', 2, '3'].some(x => x == value);
['1', 2, '3'].some(x => x === value);
['1', 2, '3'].some(x => Object.is(x, value));

This is true - guess I was assuming we were comparing against literals, where you can just make them all strings. It you're comparing with other variables, you can coerce those other variables as well when needed.

['1', String(two), '3'].includes(String(value))