type Item = { id: string }
The simplest representation of the ordered item. Used only one string property to aggregate/distinguish order items with each other. Potentially could be any Setoid.
type Price = { price: number }
This interface used to work with the prices.
Use functions addPrices()
, minusPrice()
, etc to work with prices.
The main idea is to calculate prices (costs) without rounding issue.
type Qty = { qty: number }
The interface supports aggregation of several order items in one item (by id
),
accumulating the quantity of the aggregated items.
This value considered to be integer: no rounding treatments applied.
Usually used with the Item
interface (see ItemQty
), but some functions do not need id
in context.
type Shipping = { shipping: number }
Represents the costs of the shipping (in different contexts).
So, all calculations should be done again through the functions like addPrices()
, minusPrice()
, etc.
type Total = { total: number }
Represents the "total costs" (in different contexts).
So, all calculations should be done again through the functions like addPrices()
, minusPrice()
, etc.
type Items<T extends Item> = { items: T[] }
Represents the list of items.
Here the Item
interface used to aggregate/distinguish items in the list.
type Order<T extends Total | Shipping | Items<Item>> = T & {
invoiced: T[],
refunded: T[],
canceled: T[],
}
This interface represents the main model of the library - the Order model. The order could be defined in several scopes (or all of them at the same time):
Total
Shipping
Items
(could be also more specific, than justItems<Item>
)
Also, there are 3 required fields with the array of elements
should have the same scope (type) as the order itself:
invoiced
, refunded
, and canceled
.
Should be clear from the definition - just intersections (more specific types)
type ItemQty = Item & Qty
type ItemTotal = Item & Total
type CartItem = ItemQty & Price & Partial<Total>
type Cart<T extends CartItem> = Items<T> & Shipping
type CartTotals<T extends CartItem & Total> = Cart<T> & Total
The library does not use the above interfaces but uses read-only (immutable) variants for each of them.
For example, instead of type Item = { id: string }
,
library uses type ItemRO = { readonly id: string }
.
The full list of immutable types could be found in readonly interfaces. This proves the immutability of types used in the library.
Tests do not use read-only types. This proves that functions could be used with mutable variables as well.
The immutability in tests is proved by deepFreeze
(which is based on Object.freeze
)
- README home
- Order model
- Business scenarios
- Basics (low-order functions)
- Documents
- Invariants
- Cart
- Order (high-order functions)
- Injectable API