Refactor. Improving Types.
Sergey Korsik
Posted on December 24, 2022
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))
}
What to improve
- Extract
[key: string]: number
to a separate type; - Update
age
functionplanet
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);
}
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).
Posted on December 24, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.