Typescript говорит вам, есть ли у вас значение или нет с вопросительным знаком. Тем не менее, часто вы захотите выполнить какое-то вычисление для них, и именно тогда сияет тип Option из fp-ts.
Например, допустим, у нас есть два предмета в магазине, и они могут иметь цен, и мы хотим написать функцию, чтобы получить цену на них обоих, в противном случае мы возвращаем некоторое значение, которое представляет «не для продажи». Сначала мы увидим, как мы это сделаем, в ванильной машинописи
type ShopItem = {
price?:number
}
const getPrice = (item1: ShopItem, item2: ShopItem):number | null => {
const price1 = item1.price;
const price2 = item2.price;
if (price1 && price2) {
return price1 + price2;
}
return null;
}
Это имеет несколько проблем. Во-первых, есть ошибка, потому что, если цена была 0, то товар должен быть выставлен на продажу, но вместо этого наш фальшивый чек закоротит и вернет ноль. Во-вторых, это не очень хорошо масштабируется. Если мы хотим добавить несколько элементов ShopItems или даже других типов элементов с необязательными значениями, нам нужно будет постоянно проверять, были ли эти значения нулевыми.
Теперь давайте сравним это с примером fp-ts https://codesandbox.io/s/laughing-wu-pffe3
import { some, none, ap, Option } from "fp-ts/lib/Option";
import { pipe } from 'fp-ts/lib/pipeable'
type ShopItem = {
price:Option<number> //this type will either be a Some<number> or None
}
const getPrice = (item1: ShopItem, item2: ShopItem): Option<number> =>
pipe(
some((a:number) => (b:number) => a + b),
ap(item1.price),
ap(item2.price)
);
То, как это работает, заключается в том, что мы получаем цену item1 и item2 и вводим ее в функцию сложения внутри some. Обратите внимание, что нет никаких нулевых проверок, поскольку это было абстрагировано в наш тип None.