Reputation: 318
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;
}
Upvotes: 6
Views: 14357
Reputation: 1283
While it's not possible in JS and TS, to avoid if/else mess I'm using following approach based on comparison:
const obj = {
color: "red",
size: 7,
used: false,
};
const cmp = (condition: any): boolean =>
_.isMatch(obj, condition);
switch (true) {
case cmp({ size: 7, color: "red" }): {
console.log("red 7");
break;
}
case cmp({ used: true }): {
console.log("used one");
break;
}
default: {
console.log("default one");
break;
}
}
Link to example
Also you can change approach with cmp(conditionObj) function to cmp(condition(obj)) - condition via lamda, or to direct condition in case statement without function.
Upvotes: 0
Reputation: 1094
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"
}
Upvotes: 3
Reputation: 32186
This is not possible using the JS switch statement. In JS, and TS by extension, the switch statement operates in a very straightforward way:
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")
}
Upvotes: 4