Using If Else is a super essential. But there are times when if becomes less readable and hard to scale as the number of conditions increase. As a replacement, we tend to use Switch Cases. But, with the inception of typescript the chances to write cleaner and readable code has shifted to another level. At least I find it more readable ( Maybe this is opinionated..Feel free to present your views on this ).
Now, let’s get straight to the heart of this article. Let me show you an implementation of a piece of code in three different versions.
Basically, this code transforms any sentence into different cases ( smallcase, uppercase, titlecase etc ).
Version — 1 ( If..Else.. )
export const transformCase = ({ text, format }: TransformCaseTypeProps) => {
if (format === "small") { //smallcase
return text.toLocaleLowerCase();
} else if (format === "title") { //titlecase
return text
.split(" ")
.map(
(word) => word.toLowerCase().charAt(0).toUpperCase() + word.slice(1)
)
.join(" ");
} else if (format === "upper") { //uppercase
return text.toUpperCase();
} else {
return text; // default case
}
};
This if…else code will work just fine. Also, I am not saying that using this isn’t a valid choice. But, there is also a better way with less code and a cleaner layout. Moreover, there are ways to stop the repetition of code ( like in here the if..else will just tend to increase in numbers as the conditions grow ).
Version — 2 ( Switch..Case.. )
export const transformCase = ({ text, format }: TransformCaseTypeProps) => {
switch (format) {
case "small": // smallcase
return text.toLocaleLowerCase();
case "title": // titlecase
return text
.split(" ")
.map(
(word) => word.toLowerCase().charAt(0).toUpperCase() + word.slice(1)
)
.join(" ");
case "upper": // uppercase
return text.toUpperCase();
default: // default case
return text;
}
};
This version with the switch case can surely be considered a bit cleaner because of group related cases in a structured and organized format, making it easier to follow the logic for multiple conditions in a better way. Additionally, it is easy to add new cases ( just add a new case block ) comparing to the if..else version. Nevertheless, this still requires multiple case ( repetition of code ) statements, as well as, explicit return for each case. All these making it harder to focus on the core functionality.
Version — 3 ( Object Literal )
export const transformCase = ({ text, caseName }: TransformCaseTypeProps) => {
const formatters = {
small: () => text.toLocaleLowerCase(), //smallcase
title: () => //titlecase
text
.split(" ")
.map(
(word) => word.toLowerCase().charAt(0).toUpperCase() + word.slice(1)
)
.join(" "),
upper: () => text.toUpperCase(), //uppercase
default: () => text,
};
const transform = formatters[caseName];
if (!transform) {
throw new Error(
`Invalid format: "${caseName}". Allowed formats are: ${Object.keys(
formatters
).join(", ")}`
);
}
Now, this is my suggested approach. Following are the key points based on my point of views —
Separation of Concerns
Each cases (small, title, upper, etc.) is encapsulated in its own function within the object, demonstrating the separation of concern.
Extensibility
Adding new cases is as simple as appending a new key-value pair in the object. Each new case is self-contained and doesn’t require modifying control flow logic where on the other versions, adding a new case would mean to repeat the a block ( new if..else OR new switch..case .. ), increasing code complexity as more cases are added. On top of that, this is cleaner, minimal, and better structured.
Hope you will be able to find more better aspects of this approach or maybe an entire way which is better. Feel free to share your thoughts. Ciao!
Top comments (0)