Question: I have some code:

```
enum Color {
    Red,
    Green,
    Blue
}

function getColorName(c: Color): string {
    switch(c) {
        case Color.Red:
            return 'red';
        case Color.Green:
            return 'green';
        // Forgot about Blue
    }

    throw new Error('Did not expect to be here');
}

```

I forgot to handle the `Color.Blue` case and I'd prefer to have gotten a compile error. How can I structure my code such that TypeScript flags this as an error?

Answer: 
Solution
--------

What I do is to define an error class:

```
export class UnreachableCaseError extends Error {
  constructor(val: never) {
    super(`Unreachable case: ${JSON.stringify(val)}`);
  }
}

```

and then throw this error in the default case:

```
enum Color {
    Red,
    Green,
    Blue
}

function getColorName(c: Color): string {
  switch(c) {
      case Color.Red:
          return 'red, red wine';
      case Color.Green:
          return 'greenday';
      case Color.Blue:
          return "Im blue, daba dee daba";
      default:
          // Argument of type 'c' not assignable to 'never'
          throw new UnreachableCaseError(c);
  }
}

```

I think it's easier to read than the function approach recommended by Ryan, because the `throw` clause has the default syntax highlighting.

Hint
----

The [ts-essentials](https://github.com/krzkaczor/ts-essentials) library has a class [UnreachableCaseError](https://github.com/krzkaczor/ts-essentials#exhaustive-switch-cases) exactly for this use-case

Runtime considerations
----------------------

Note, that typescript code is transpiled to javascript: Thus all the typescript typechecks only work at compile time and **do not** exist at runtime: i.e. there is no guarantee that the variable `c` is really of type `Color`.  

This is different from other languages: e.g. Java will also check the types at runtime and would throw a meaningful error if you tried to call the function with an argument of wrong type - but javascript doesn't.

This is the reason why it is important to throw a meaningful exception in the `default` case: [Stackblitz: throw meaningful error](https://stackblitz.com/edit/unreachable-case-error)

If you didn't do this, the function `getColorName()` would implicitly return `undefined` (when called with an unexpected argument): [Stackblitz: return any](https://stackblitz.com/edit/unreachable-case-return-any)

In the examples above, we directly used a variable of type `any` to illustrate the issue. This will hopefully not happen in real-world projects - but there are many other ways, that you could get a variable of a wrong type at runtime.  

Here are some, that I have already seen (and I made some of these mistakes myself):

* using angular forms - these are not type-safe: all form field-values are of type `any`  

[ng-forms Stackblitz example](https://stackblitz.com/edit/angular-forms-types)
* implicit any is allowed
* an external value is used and not validated (e.g. http-response from the server is just cast to an interface)
* we read a value from local-storage that an older version of the app has written (these values have changed, so the new logic does not understand the old value)
* we use some 3rd party libs that are not type-safe (or simply have a bug)

So don't be lazy and write this additional default case - it can safe you a lot of headaches...
Building on top of [Ryan](https://stackoverflow.com/a/39419171/626911) and [Carlos'](https://stackoverflow.com/a/58009992/626911) answers, you can use an anonymous method to avoid having to create a separate named function:

```
function getColorName(c: Color): string {
  switch (c) {
    case Color.Red:
      return "red";
    case Color.Green:
      return "green";
    // Forgot about Blue
    default:
      ((x: never) => {
        throw new Error(`${x} was unhandled!`);
      })(c);
  }
}

```

If your switch is not exhaustive, you'll get a *compile* time error.