DEV Community

Sergey Korsik
Sergey Korsik

Posted on • Edited on

Refactor. Improving Types.

Hi!
Today we will take a look on the planets and age on them (relative).

Instructions

Given an age in seconds, calculate how old someone would be on:
Mercury: orbital period 0.2408467 Earth years
Venus: orbital period 0.61519726 Earth years
Earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31557600 seconds
...[omitted, full list in the task]
So if you were told someone were 1,000,000,000 seconds old, you should be able to say that they're 31.69 Earth-years old.

First solution

As a basement we will take quite nice solution and will see what can be improved from the types perspective (i.e. make them more restrictive and "extracted") as well as we will apply clean code practices:

const RATIOS: {
  [key: string]: number
} = {
    mercury: 0.2408467,
    venus: 0.61519726,
    earth: 1,
    mars: 1.8808158,
    jupiter: 11.862615,
    saturn: 29.447498,
    uranus: 84.016846,
    neptune: 164.79132
}
export function age(planet: string, seconds: number): number {
    return Number((seconds / 31557600 / RATIOS[planet]).toFixed(2))
}
Enter fullscreen mode Exit fullscreen mode

What to improve

  • Extract [key: string]: number to a separate type;
  • Update age function planet parameter type to more specific;
  • extract fix of result in the separate function;
  • add 31557600 as constant;
  • change function to an arrow function (just love it!);

some typing.. and...

Second solution

Here I've tried to reflect all the above mentioned points. There is a result:

type PlanetCoefsType = {
  [key: string]: number
};

const PlanetCoefs: PlanetCoefsType = {
  mercury: 0.2408467,
  venus:  0.61519726,
  earth: 1.0,
  mars: 1.8808158,
  jupiter: 11.862615,
  saturn: 29.447498,
  uranus: 84.016846,
  neptune: 164.79132,
}

type Planet = keyof typeof PlanetCoefs;

const YEAR_ON_EARTH_IN_SEC = 31557600;

const fixToTwo = (rawValue: number): number => Number(rawValue.toFixed(2));

export const age = (planet: Planet, seconds: number): number => {
  const planetCoef = PlanetCoefs[planet];
  const result = seconds / YEAR_ON_EARTH_IN_SEC / planetCoef;
  return fixToTwo(result);
}
Enter fullscreen mode Exit fullscreen mode

All the changes I would assume quite trivial and easy to follow, except maybe this one (at least for me it took some time to understand):
type Planet = keyof typeof PlanetCoefs;

In this case the intention is to extract on programmatic level all already listed in PlanetCoefs object names of planets and strict our code to this list as we do not support others, i.e. "pluto", "solaris" and so on.

Hope it was a bit useful and interesting!
In the next post I will put an example with RegExp (how to add them or remove if too scared:)).

Meanwhile you can take a look on interesting example from the previous post (crazy one-liner and easy readable solution).

Top comments (0)