Consider the case of type conversion of nulls

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the dumb-mistakes-and-gotchas category.

Last Updated: 2024-11-21

I had the following function as part of a tax calculator:

// userInput is JSON
function calculateNursingInsurance(userInput) {
  const isChildless = Number(userInput["number_children"]) == 0
  const age = new Date(Date.now()).getFullYear() - Number(userInput["year_of_birth"])
  // lots more code using other data properties
  // ...
  }

When this function was first put into action, the userInput parameter always contained the keys number_children and year_of_birth.

But as the codebase grew, I re-used this function elsewhere, and passed it a userInput object absent some of the properties the internals expect, i.e. absent number_children and year_or_birth. The code "worked" (in the narrow sense of giving a numerical answer) so I assumed everything was OK.

But in fact there were grave errors and inaccuracies. For example, if no year_of_birth was present, then this key's value would be null and Number(null) in JavaScript gives 0, and the age, which is calculated as the current year minus year of birth, would become 2020, a ripe old age indeed.

Lesson:

When doing conversions of inputs into numbers, consider what happens if they are null. In the JavaScript case, is 0 acceptable - or should there be an error thrown?

Generally be very careful within a function that blindly accepts input without some type-checking or bounds checking. Just because the input "always" has this data now, doesn't mean it will in future.