3

I am trying to switch on an enum so that the correct code is run. I have made a typescript playground that showcases a small example of what I am trying to accomplish.

In the provided example I am trying to understand why Test1 will not print "B". My expectation is that when the logical OR is used it will try to check if either case is true. Not just the first one. Might this be a misunderstanding of some fundamentals? Test2 works because I am explicitly stating the cases, but Test1 would be a more compact version.

enum EventType {
    A = "A",
    B = "B",
    C = "C",
}

function Test1(type: EventType) {
    switch(type) {
        case EventType.A || EventType.B:
            console.log("Test1", type);
            break;
        case EventType.C:
            console.log("Test1", type);
            break;

    }
}

function Test2(type: EventType) {
    switch(type) {
        case EventType.A:
        case EventType.B:
            console.log("Test2", type);
            break;
        case EventType.C:
            console.log("Test2", type);
            break;

    }
}

const e = EventType.B;
Test1(e); // Expect "B" to print but does not
Test2(e); // Expect "B" to print and it does

Typescript Playground

darophi
  • 456
  • 5
  • 15
  • At SO, it's important that your question is able to stand-alone without requiring information at the end of a 3rd-party link (sometimes, they rot away). Rule-of-thumb: If you remove the links from your question, is it still answerable? It should be. Please add the code from the playground into the question body itself. – spender Jan 28 '21 at 10:15
  • 1
    My bad. Has been added. Thanks for the reminder – darophi Jan 28 '21 at 10:23

2 Answers2

3

Because you expect EventType.A || EventType.B evaluate to true, you should explicitly use true in your switch statement.


enum EventType {
    A = "A",
    B = "B",
    C = "C",
}

function Test1(type: EventType) {
    switch(true) {
        // you should use next approach if you want to mix boolean end enums
        case type === EventType.A || type === EventType.B:
            console.log("Test1", type);
            break;
        case type === EventType.C:
            console.log("Test1", type);
            break;

    }
}

function Test2(type: EventType) {
    switch(type) {
        case EventType.A:
        case EventType.B:
            console.log("Test2", type);
            break;
        case EventType.C:
            console.log("Test2", type);
            break;

    }
}

const e = EventType.B;
Test1(e); // Expect "B" to print and it does it
Test2(e); // Expect "B" to print and it does

TypeScript like JS does not have advanced swith patterns like Rust, F#, Reason etc ...

  • Hmm. That makes sense. I guess I was thinking along the lines of pattern matching and totally disregarded the fact that I am actually evaluating to a boolean. – darophi Jan 28 '21 at 10:25
  • Rust has really powerful mechanism of pattern matching https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html – captain-yossarian from Ukraine Jan 28 '21 at 10:26
  • 1
    @captain-yossarian Yes, although this was mainly inherited from Rust's [ML roots](https://en.wikipedia.org/wiki/Standard_ML#Algebraic_datatypes_and_pattern_matching). – spender Jan 28 '21 at 12:41
1

Your problem is in fundamentals. The term you are looking for is called fall-through.

To evaluate multiple cases in a switch-statement for fall-through, you write multiple cases grouped with the same break.

Fall-through Example

switch(foo) {
 case A:
 case B:
  /* statements for both A and B */
 break;
 case C:
 /* statements for C */
}
Mikkel Christensen
  • 2,502
  • 1
  • 13
  • 22
  • I know that fall-through applies. This is why Test2 works fine. I just assumed that Test1 example would represent a shorthand for the case A: case B: code(); break; – darophi Jan 28 '21 at 09:31