Предотвратете скрити грешки чрез прилагане на специфични за домейна типове към вашите примитиви

Типовите анотации са основата за добре документирана кодова база. В резултат на това нашият код става четим и поддържаем, което ни помага да го поддържаме с нарастването на размера и сложността на проекта.

Помага ни да опишем нашите обекти на домейн за свойство, като User { name: string; email: string; } или Transaction { amount: number; status: TransactionStatus }.

Типът стойност се декларира чрез анотация. Не трябва да гадаете за типа на стойността по име на променлива или да намирате мястото, където е била присвоена.

Работи добре за съставни типове, така че защо да не го приложите и към примитивни типове?

Нека да разгледаме следния пример.

type Time = {
  hours: number;
  minutes: number;
}

const formatTime = (duration: number): Time => {
  const time = duration / 1000;
  ...
}

Функцията получава аргумент duration от тип номер и трябва да форматира правилния тип Time. Както можете да видите, е доста трудно да сте сигурни за типа на аргумента duration, без да проверите самото изпълнение на функцията, защото може да варира от милисекунди до секунди или дори да бъде някаква друга стойност.

Нека да разгледаме втория пример.

type Time = {
  hours: number;
  minutes: number;
}

const formatTime = (duration: Millisecond): Time => {
  const time = duration / 1000;
  ...
}

Тук можем да видим, че аргументът duration има тип Millisecond, така че когато разглеждаме сигнатурата на функцията, можем да сме сигурни какъв вид стойност приема и да я извикаме, без да навлизаме дълбоко в изпълнението.

const PERMISSIBLE_SPEED = 60;

const permissibleSpeedExceeded = (speed: number) => {
  return speed > PERMISSIBLE_SPEED;
};

Вие ще попитате дали тази функция приема мили или километри. Вашият клиент може да има проблеми, ако объркате KM/H с MPH :)

Смятате ли, че това е въображаема ситуация? Прочетете за как НАСА загуби един от космическите си кораби (Mars Climate Orbiter) поради метрична математическа грешка на 23 септември 1999 г. и което доведе до скъпоструваща загуба от $125 милиона ($229 милиона в днешна валута). Накратко, мисията беше неуспешна поради грешка в навигацията, причинена от неуспешен превод на английски единици в метрични.

const PERMISSIBLE_SPEED: KM_H = 60;

const permissibleSpeedExceeded = (speed: KM_H) => {
  return speed > PERMISSIBLE_SPEED;
};

Както можете да видите, тялото на функцията е същото, но има повече смисъл със смислени пояснения към типа.

Можете да експериментирате с по-примитивни типове като ID {string}, Age {number} или процент {number} по отношение на вашия конкретен домейн.

Заключение

Използването на специфични за домейна типове за примитиви, като милисекунди, секунди, KM, ID и т.н., носи значителни ползи за нашата кодова база и помага на членовете на нашия екип да работят по-гладко върху нея. Тези смислени типови анотации подобряват четливостта и поддръжката на кода, като стават особено ценни, когато вашият проект и бизнес домейн нарастват в сложност. Като изрично декларираме типове стойности, ние елиминираме догадките и минимизираме грешките, правейки нашия код по-стабилен.

TL;DR
Използвайте смислени специфични за домейна типове за примитиви като Second, KM и ID и т.н. Тези анотации на типове имат повече смисъл от низове, числа и плаващи числа.

Надяваме се, че това ще бъде полезно за вас и вашия екип и ще ви позволи да се съсредоточите върху важни неща!