Why is 1<x<3 always true?

Viewed 374

I'm learning TypeScript, and in the getting started page, they talk about how unexpected javascript is.

Source: https://www.typescriptlang.org/docs/handbook/typescript-from-scratch.html

if ("" == 0) {
// It is! But why??
}
if (1 < x < 3) {
// True for *any* value of x!
}

But I still don't understand why 1<x<3 is always true? For example if I let x=10, it will not be true by logic, but why they said it always true?

2 Answers

1 < x < 3 actually is doing this:

(1 < x) < 3

Or even more long form:

const tempVarA = 1 < x
const tempVarB = tempVarA < 3

So 1 < x is either true or false. Then the next step is true < 3 or false < 3. Those don't make much sense as comparisons, but let's see what javascript does with that:

console.log(true < 3) // true
console.log(false < 3) // true

Weird, but let's dig deeper:

console.log(true >= 0) // true
console.log(true >= 1) // true
console.log(true >= 2) // false

console.log(false >= 0) // true
console.log(false >= 1) // false
console.log(false >= 2) // false

It seems that true is being treated as 1 and false is being treated as 0. To verify that let's compare with == (instead of ===) so that it coerces the type of the data for us.

console.log(true == 1) // true
console.log(true == 0) // false
console.log(false == 1) // false
console.log(false == 0) // true

So 1 < x < 3 is always true because false becomes 0 or true becomes 1, and both 0 and 1 always less than 3.


Explanation:

in javascript, comparison operators <, <=, >, >=, ==, and != coerce their operands to make them comparable when they are different types. So when comparing a boolean to a number it coverts the boolean to a number, 0 or 1.

This is why you should almost always use === instead of ==, and why this is a type error in typescript:

const a = true < 3
// Operator '<' cannot be applied to types 'boolean' and 'number'.(2365)

Short version

Javascript and typescript lack a chainable comparison operator.

Did you mean to do this?

1 < x && x < 3

in other words: true is 1 and false is 0. Therefore 1 < x < 3 with x = 5 is as if it executes (1 <5) <3 and writes to 1 <5 = 1 (true) and then 1 <3 = 1 (true). If instead x were 0? Ok 1 <0 is false (0) consequently 0 <3 is true (1)

Related