Before I discuss the style, let me explain the problem I’m trying to solve. It’s not uncommon for switch statements to have somewhat-repeated code between cases, but with variations in each case such that you can’t easily abstract it. Let’s take this example, written in ES5 (I promise there’s a reason why).

switch (body.type) {
  case 'isBasic':
    var entry = getBasicEntry(body.id);
    console.log('Processing basic entry "' + entry.name + '"');
    doBasicProcessing(entry);
    break;

  case 'isCustom':
    var entry = getCustomEntry(body.id);
    console.log('Processing custom entry "' + entry.name + '"');
    doCustomprocessing(entry);
    break;

  default:
    throw new Error('Unknown flag ' + myFlag);
}

Cool, it’s a basic switch statement and it works fine. Now, let’s convert this to ES2015+.

switch (body.type) {
  case 'isBasic':
    const entry = getBasicEntry(body.id);
    console.log(`Processing basic entry "${entry.name}"`);
    doBasicProcessing(entry);
    break;

  case 'isCustom':
    const entry = getCustomEntry(body.id);
    console.log(`Processing custom entry "${entry.name}"`);
    doCustomprocessing(entry);
    break;

  default:
    throw new Error(`Unknown flag ${myFlag}`);
}

Uh-oh, we now get a SyntaxError exception when we run this code! The problem here is that const variable name entry cannot be declared twice in the same scope. Because of how scoping rules work, the entire switchstatement is one single scope.

We could solve this by naming each entry with a different variable name, but honestly I find that kind of annoying. We could also create a helper function for each case, but that feels excessive to me for such short case statements.

So here’s what I figured out, and I’ve started using it in all my code:

switch (body.type) {
  case 'isBasic': {
    const entry = getBasicEntry(body.id);
    console.log(`Processing basic entry "${entry.name}"`);
    doBasicProcessing(entry);
    break;
  }

  case 'isCustom': {
    const entry = getCustomEntry(body.id);
    console.log(`Processing custom entry "${entry.name}"`);
    doCustomprocessing(entry);
    break;
  }

  default: {
    throw new Error(`Unknown flag ${myFlag}`);
  }
}

I wrap each case statement in {}, which creates a new scope on a per-case basis. This solves the problem, and I think is kind of elegant myself. It’s not very common though.

#javascript

A New Coding Style for Switch Statements in JavaScript/TypeScript
28.90 GEEK