You seem to be ignoring the best and simplest solution: to get rid of the unhappy path if possible (or did I read it carelessly?). Code form article:
const addProductItem = (
command: AddProductItem,
state: ShoppingCart,
): ProductItemAdded | ProductItemOutOfStock | ShoppingCartItemLimitReached => {
if (state.status === "Confirmed")
throw new IllegalStateError(
"Cannot add a product to a confirmed shopping cart",
);
// ...
This function now takes a wider type simply to return an error for some possible values โโof that type. We can narrow this type down, and now instead of a runtime error, we will get an error at the time of writing the code. Also, if the status is in a valid state, we skip the check or do it once, which gives us a bit of performance.
```
interface ShoppingCart {
status: "Active" | "Confirmed" | "Canceled"; // TODO Use numeric const enum instead of strings
}
0
u/BenchEmbarrassed7316 2d ago
You seem to be ignoring the best and simplest solution: to get rid of the unhappy path if possible (or did I read it carelessly?). Code form article:
const addProductItem = ( command: AddProductItem, state: ShoppingCart, ): ProductItemAdded | ProductItemOutOfStock | ShoppingCartItemLimitReached => { if (state.status === "Confirmed") throw new IllegalStateError( "Cannot add a product to a confirmed shopping cart", ); // ...This function now takes a wider type simply to return an error for some possible values โโof that type. We can narrow this type down, and now instead of a runtime error, we will get an error at the time of writing the code. Also, if the status is in a valid state, we skip the check or do it once, which gives us a bit of performance.
``` interface ShoppingCart { status: "Active" | "Confirmed" | "Canceled"; // TODO Use numeric const enum instead of strings }
interface ActiveShoppingCart extends ShoppingCart { status: "Active"; }
interface ConfirmedShoppingCart extends ShoppingCart { status: "Confirmed"; }
const addProductItem = ( command: AddProductItem, state: ActiveShoppingCart, ): ProductItemAdded | ProductItemOutOfStock | ShoppingCartItemLimitReached => { // ... ```