Equivalent of multiple expressions in a typescript switch statement

Viewed 2917

Since

switch(1 === 1, 2 === 2) {
    case true, true:
        console.log("true, true");
        break;
    default:
        console.log("default");
        break;
}

doesn't work(only goes off of the right side of the comma to my knowledge), I was wondering if there was a typescript equivalent to something like rust's match:

match(1 == 1, 2 == 2) {
    (true, true) => println!("true, true"),
    _ => println!("default"),
}

I've tried doing something with tuples but it always goes to the default condition, see below for code.

switch([1 === 1, 2 === 2]) {
    case [true, true]:
        console.log("true, true");
        break;
    default:
        console.log("default");
        break;
}
2 Answers

This is not possible using the JS switch statement. In JS, and TS by extension, the switch statement operates in a very straightforward way:

  • Evaluate the expression in the switch.
  • Compare it (strictly) with each case.

So the behavior you see is caused in part by both of those actions. The first thing to understand is that using a comma doesn't work because that is interpreted as an expression using the comma operator, which as you noticed simply results in the value of the final comma'd expression.

For your second attempt, it is hitting the default expression because under strict comparison, two objects are equal only if they are the same reference. So using an array literal in your switch produces a new array object (reference) which will never be equal to the different references created by the literals in each case.

In order to get the behavior you want, you have to do that comparison the old fashioned way: manually using a collection of if statements. That will allow you to compare each item in your tuple individually. Perhaps something like:

function compareTuples(tup1, tup2) {
  if (tup1.length !== tup2.length) return false;
  return tup1.every((value, index) => tup2[index] === value);
}

const base_tuple = [1 === 1, 2 === 2]

if (compareTuples(base_tuple, [true, true])) {
  console.log("Matched [true, true]")
} else if (compareTuples(base_tuple, [true, false])) {
  console.log("Matched [true, false]")
} else {
  console.log("Matched default")
}

not sure if this is what you're looking for but maybe you could use this as a workaround

const tuple: [number, number] = [3, 3]

switch (tuple.join(",")) {
    case "3,3": 
      console.log('1');
      break;
    case "3,4":
      console.log('2');
      break;
    default: throw "invalid"
}
Related