https://github.com/aneldev/dyna-switch
Inline switch that returns value. Write complex switch in clean way.
https://github.com/aneldev/dyna-switch
Last synced: 9 months ago
JSON representation
Inline switch that returns value. Write complex switch in clean way.
- Host: GitHub
- URL: https://github.com/aneldev/dyna-switch
- Owner: aneldev
- License: mit
- Created: 2020-12-06T11:06:03.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2023-09-28T07:35:49.000Z (over 2 years ago)
- Last Synced: 2025-07-18T19:16:54.499Z (11 months ago)
- Language: JavaScript
- Size: 185 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# dynaSwitch
`dynaSwitch` combines the benefits of JavaScript's `switch` statement and allows inline value returns.
# How to use JavaScript's switch statement for inline value
Suppose we have the following themes:
```typescript
interface ITheme {
color: string;
backgroundColor: string;
}
const lightTheme: ITheme = {color: 'black', backgroundColor: 'white'};
const darkTheme: ITheme = {color: 'white', backgroundColor: 'black'};
const redTheme: ITheme = {color: 'red', backgroundColor: 'white'};
```
We can write the following code to obtain the appropriate theme based on a string value:
```typescript
const themeName: string = getUIThemeName();
const theme: ITheme = (() => {
switch (themeName) { // The value that is going to be tested
case 'light': // The cases
return lightTheme;
case 'dark':
return darkTheme;
case 'red':
return redTheme;
default:
return lightTheme; // Default value
}
})();
```
# Introducing `dynaSwitch`
With `dynaSwitch`, we can achieve the same result in a more concise manner:
```typescript
const themeName: string = getUIThemeName();
const result = dynaSwitch(
themeName, // The value that is going to be tested
lightTheme, // Default value
{ // Cases (as object)
light: lightTheme,
dark: darkTheme,
red: () => redTheme, // The value would be returned by a function also
},
);
```
**Benefits**
- Organized like JavaScript's `switch` statement
- Less code, more readable
- Prevents accidental fall-through cases
- Always returns a value (the second argument serves as the default value)
- Provides type safety in TypeScript, ensuring the expected value is returned
- The `cases` dictionary argument can be reused and can handle more complex objects.
# Using `dynaSwitch` with functions
In this example, we utilize functions instead of values in the `dynaSwitch` cases. This allows us to have variables with the same names inside the functions, something not possible with the traditional `switch` statement unless closures are used. This feature is particularly useful in `Redux reducers`, where the cases often require the use of the same variable names.
```typescript
const themeName: string = getUIThemeName();
const result = dynaSwitch(
themeName, // The value that is going to be tested
lightTheme, // Default value
{ // Dictionary with the cases
light: () => {
const isUserAdmin: boolean = getUserAdmin();
const theme = { ...lightTheme };
theme.profile.color = 'red';
return theme;
},
dark: () => {
const isUserAdmin: boolean = getUserAdmin();
const theme = { ...darkTheme };
theme.profile.color = 'maroon';
return theme;
},
red: () => {
const isUserAdmin: boolean = getUserAdmin();
const theme = { ...redTheme };
theme.profile.color = 'pink';
return theme;
},
},
);
```
# Introducing `dynaSwitchEnum`
With `dynaSwitchEnum`, you can easily achieve super type-safe values for each option of an Enum, thanks to TypeScript's internal `Record` feature. This means that if the Enum is modified in the future, you will receive TypeScript errors during compilation for any missing or modified Enum options.
```typescript
enum ETheme {
DARK = "DARK",
LIGHT = "LIGHT",
REDISH = "REDISH",
}
interface ITheme {
color: string;
backgroundColor: string;
}
const themeSetups: Record = {
[ETheme.LIGHT]: {
color: 'black', backgroundColor: 'white',
},
[ETheme.DARK]: {
color: 'white', backgroundColor: 'black',
},
[ETheme.REDISH]: {
color: 'red', backgroundColor: 'white',
},
};
dynaSwitchEnum(ETheme.LIGHT, themeSetups).color; // returns "black"
dynaSwitchEnum("something", themeSetups).color; // not compilable, due to TS!
```
Alternatively, you can define the dictionary directly. This is especially helpful when you want to convert an enum to a React component prop.
```
dynaSwitchEnum(
ETheme.REDISH,
{
[ETheme.LIGHT]: 'Light',
[ETheme.DARK]: 'Darky',
[ETheme.REDISH]: 'Redish',
},
); // This returns "Redish"!
```
**Benefits**
- Provides super type safety for both the Enum and the returned value
- Always returns a value
# Introducing `dynaSwitchIf`
`dynaSwitchIf` is similar to `dynaSwitch`, but instead of using a dictionary, it employs an array of "if" statements. The first valid "if" statement is executed. This approach makes it easier to assign values compared to using keys in a dictionary.
This `dynaSwitch` implementation works like an "if-else" statement.
Example:
```typescript
const themeName = 'dark';
const theme = dynaSwitchIf(
themeName, // The value that is going to be tested
lightTheme, // Default value
[
{if: 'light', then: lightTheme},
{if: 'dark', then: () => darkTheme}, // The `then` would be a function
{if: 'red', then: redTheme},
],
);
expect(theme.color).toBe('white');
```
# API
TypeScript signatures of the methods:
## dynaSwitch
```typescript
export interface IDynaSwitchCasesDic {
[enumCase: string]: TResult | (() => TResult);
}
export const dynaSwitch = (
testValue: TTestValue,
defaultValue: TResult | (() => TResult),
cases: IDynaSwitchCasesDic,
) => TResult;
```
## dynaSwitchEnum
```typescript
export const dynaSwitchEnum = (
testValue: TEnum,
cases: Record,
) => TResult;
```
## dynaSwitchIf
```typescript
export type TDynamicValue = T | (() => T);
export const dynaSwitchIf = (
testValue: TTestValue,
defaultValue: TDynamicValue,
cases: { if: TDynamicValue; then: TDynamicValue }[],
) => TResult;
```