1
\$\begingroup\$

How to reduce code size?

  getAlreadySaved(goal: GoalModel): number {

        if (goal.status && goal.status.investedAmount && !goal.status.pendingIncoming && !goal.status.pendingOutgoing) {
            return goal.status.investedAmount;

        } else if (goal.status && goal.status.investedAmount && goal.status.pendingIncoming && !goal.status.pendingOutgoing) {
            return goal.status.investedAmount + goal.status.pendingIncoming;

        } else if (goal.status && goal.status.investedAmount && !goal.status.pendingIncoming && goal.status.pendingOutgoing) {
            return goal.status.investedAmount - goal.status.pendingOutgoing;

        } else if (goal.status && goal.status.investedAmount && goal.status.pendingIncoming && goal.status.pendingOutgoing) {
            return goal.status.investedAmount + goal.status.pendingIncoming - goal.status.pendingOutgoing;

        } else {
            return 0;
        }

    }
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Find invalid cases first then return early. In this case, it looks like the initial goal.status check is primarily for presence check. You can remove that from the entire logic and put it up front, returning 0 early.

Now the whole point of TypeScript is to provide types to your data so you won't be doing unnecessary type checks in code. In the case of pendingIncoming, pendingOutgoing and investedAmount, they're numbers. The type for status should at least define them as number. Without a value, they should at least be initialized to 0. That should remove the unnecessary conditions.

With that, your code is essentially just:

getAlreadySaved(goal: GoalModel): number {
  const status:Status = goal.status;

  if(!status) return 0;

  // If we can assume they're numbers, we can safely say we can do math.
  return status.investedAmount + status.pendingIncoming - status.pendingOutgoing;
}
\$\endgroup\$
4
  • \$\begingroup\$ Even if investedAmount, pendingIncoming, and pendingOutgoing are declared as numbers, they can easily get null/undefined in run time. I got burnt many many times by the objects received from API calls. What I am saying is not that your code is bad with this assumption, but that there's an issue with the assumption itself. \$\endgroup\$ Commented May 1, 2017 at 0:53
  • \$\begingroup\$ Also, there's no point in the :Status part of the status declaration. Compiler will infer the type very well, and there's no much value in making the type explicit at this point. \$\endgroup\$ Commented May 1, 2017 at 0:55
  • \$\begingroup\$ @IgorSoloydenko Getting null/undefined on runtime, particularly when using TypeScript, is a sign of a much bigger problem. I'd solve that problem instead of making workarounds and defeating the purpose of TS. Also, Status was to clarify that status is of Status because it's not mentioned in the question. \$\endgroup\$
    – Joseph
    Commented May 1, 2017 at 1:25
  • \$\begingroup\$ "sign of a much bigger problem" -- not necessarily, especially when front-end talks to an API we don't have control over. Nobody says that workaround is a good idea, but your assumption was too broad. If the API guarantees non-null values for the fields, the code is fine. The Status type would be better described by explicit type declaration, rather than status: Status = ... since, as I said it's inferred anyway. \$\endgroup\$ Commented May 1, 2017 at 7:29

Your Answer

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