0
\$\begingroup\$

I have a typescript function that executes an array of actions on a given string value. This is the code:

    processValue(value: string, actions: Action[]): any {
        actions?.forEach((action: Action) => {
            switch (action.type) {
                case ActionType.Append: {
                    const { appendText } = action as Append;
                    value = this.append(value as string, appendText);

                    break;
                }
                case ActionType.ComposeUrl: {
                    const { baseUrl } = action as ComposeUrl;
                    value = this.composeUrl(value as string, baseUrl);

                    break;
                }
                case ActionType.ConvertNumber: {
                    value = this.convertToNumber(value as string);

                    break;
                }
            }
        });
        
        return value;
    }

ActionType is an enum that contains all the possible actions and Action is like type Action = Append | ComposeUrl |ParseJson, each action is an interface we the needed properties to perform the action.

I wanted to ask if there's a better way to write it because the more actions I add, the longer becomes the switch statement.

I was reading about Strategy Pattern and Visitor Pattern but I don't know if they are applicable because of the different number and type of arguments I need in each function and because it's not completely crear to me how to implement them.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I think that you are trying to create a pipe. Something like this would probably work:

interface Action {
  execute(value: string): string
}

class AppendAction implements Action {
  constructor(private appendText: string) {}

  execute(value: string) {
    return value + this.appendText
  }
}

function pipe(value: string, ...actions: Action[]) {
  return actions.reduce((accumulator, action) => action.execute(accumulator), value)
}

pipe("test", new AppendAction("is"))

To get really fancy you can do:

function append(text: string) {
  return new AppendAction(text)
}

pipe("test", append("is"))

I might be wrong, but I think this is a variant of strategy pattern. You get around the different number of parameters by having one input object and parameters that would typically be function parameters become constructor parameters. If you have multiple input parameters, make them an object.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.