TypeScript: Use polymorphism in place of the switch and other conditionals

Write better code with OOP principles.

Oleh Baranovskyi

--

In the beginning, I was using the switch statements as much as possible. To me, it looked perfect, until someday I came across a “Clean Code” book. Robert C. Martin clearly explains why switch statements might be a lousy construction and why we might reconsider and stop using them everywhere.

With time and gained experience, I was using the switch statements less, and later on, I didn’t see the reason to use them at all. In this article, I want to share one of the approaches that I’m using on the projects in place of switch statements. It’s called polymorphism, one of the OOP principles.

Why might you want to reconsider using the switch statements?

`switch` statements always lead to very long methods, dozens of conditions and every instruction requires at least few lines of code plus break. Robert C. Martin in his book “Clean Code” says that method “Should be as small as possible”.

Moreover switch statement is unreadable and not extendable.

Having to sift (Multi-case — single operation) through hundreds of conditionals is not user friendly and it can be confusing for others.

In one switch statement can be mixed totally different logic and of course it is wrong because method “Should do one thing only and do it well.”

What do we have here, a switch statement?

Here is the initial code that we will refactor during this article. We have one switch statement and fruit enum.

We can get rid of the switch statement as we only need the enum.

Let’s get rid of the switch statement

First, let’s add an abstract class called Fruit, representing the base entity with the price.

Fruits class should be abstract because we do not want to create a base class instance. Inherited classes will supply price value.

Here you can see that we’ve used a Record utility type. If you want to get more info about utility types, you can find it here:

Now, let’s add a function that will supply the correct constructor.

We’re ready to make a first test drive:

Overloading the constructor factory function

Sometimes, it’s convenient to pass a string instead of the enum value. For instance, we might get a string from the HTML template, for which we should return the price.

But before we update our constructor factory function, we need to add one more function that will help us to work with the enums:

It simply takes enum and returns an array with tuples. Each tuple consists of the enum name and value.

To work with strings and enum values, we need to update our constructor factory function:

Let’s test findFruitConstructor function by passing the string value:

Supplying default behavior with Nullable pattern

What will happen in the case if somehow we will get the name of the constructor which does not exist?

We will get an error.

To prevent this and have a default behavior for the not existing fruit, we can use a Nullable pattern in place of error.

Let’s add a Nullable interface:

Fruit class should implement the Nullable interface and .isNull() method, which has to return false.

We also need to add NullableFruit class that will represent fruit with no behavior:

Now we need to return a NullableFruit constructor instead of throwing an error.

And here is the final demo:

It seems to be working as expected. Moreover, we’ve added many useful features along the way, and it’s possible to add many more. It’s one of the proposed approaches, and there are others. All of them that do not use switch statements are super flexible.

Conclusion

I hope you found this article interesting and came across new techniques. Please feel free to reach out if you have any questions.

Hit the 👏👏👏 button and subscribe, which will motivate me to write more articles.

--

--