Railway Oriented TypeScript Robin Pokorny
A presentation at WebExpo 2022 in June 2022 in Prague, Czechia by Robin Pokorny
Railway Oriented TypeScript Robin Pokorny
Example A Simple Response To A Request Happy-Path Code What if data is not valid? const action = (req, res) 1 validate(req); { const newData = updateDB(req.body); 2 log(newData); 3 return res.send(newData); }; > 2 = What if log fails? What if the DB is unreachable?
Functional Programming Don’t leave! 3
Monad Semigroup Category Sum type Functor Foldable
Erlang Haskell I ❤ FP Closure
Next 40 minutes 1 2 3 Show TypeScript Code Don’t tell But, why? Yes, really 6
Scott Wlaschin Railway Oriented Programming 7
””“”” “”“”“”“”“” ” “”“”“”“” “”“”“”“” “”“”“”“”” “” “”“”“”” “” “”“”“”“”“”“” “” “”” “”” “”“”” “”“”” “”“”“”“”“”“”“” “”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“” “”“”“”“”” “”“”“”“”” “”“”“” “”“”“”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“” “”” “”“”” “”“”“” “”“”“”“” ” “” “” ” “”“”” “”“”” ” “”“”“”“”“”” “”“”” “”“” ” “”“”“”“” “”“”“”“”“”” ” “”“”“”“” “”” “”“”“” “”” “”“”“”“”” “”” “” “”“”“”” “”“”“”” “”“” “”“”“”“”” “”“”” “”“”“”“”“” “”“”” “”“”“” “”” “”“” “”“”“” “”“”“”” “”“”“”“”“”“”“”” “”“”“” “” ” “”“”“”“”“”“”“”“”“” ” “”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”” “”“” “” ” “”“”“”“”“”“”“”” “” “”“”“”“” “”“”” “”“” “”” “”“”“”“”“”“”” “” ” “”“”“”“”“”“”“” “” “”“”“”“”“”” “”” “”“”“”“”“” ” “”“”“”“”“”“”“”“”“”“”” “”“”“” “”“”“”“”“”“”“”” “”” ” “”“” ” “”“”“”“”“”“”“”“”“”“”“”“”“” “”“”” “”“” “”“”“”“”“”“”” ” “” “”“”“” “”” “” “” “” “” “”“”“” ” “”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” ” “”“”” “”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”” “”“” “” ” “”“”“”“”“”” “” “”“”“”” “”“”“”“”“”” “”” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “”“”“”“”“”“”” “” “” 8
🍏 🍌 Function Apple -> Banana 9
🍏 🍌 🍌 🍏 🍓 🍓 10
const action = (req, res) validate(req); { const newData = updateDB(req.body); log(newData); return res.send(newData); const action = (req, res) { const { value, error } = validate(req); if (error null) { return res .status(400) .send(“Invalid request”); } 💥 let newData; }; try { newData = updateDB(req.body); } catch (e) { log(e) return res .status(500) .send(“Something went wrong 🤷”); } 💥 💥 try { log(newData); } catch (e) { Just log the logging error log(e) } return res.send(newData);
= ! / / }; 11
””“”” “”“”“”“”“” ” “”“”“”“” “”“”“”“” “”“”“”“”” “” “”“”“”” “” “”“”“”“”“”“” “” “”” “”” “”“”” “”“”” “”“”“”“”“”“”“” “”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“” “”“”“”“”” “”“”“”“”” “”“”“” “”“”“”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“” “”” “”“”” “”“”“” “”“”“”“” ” “” “” ” “”“”” “”“”” ” “”“”“”“”“”” “”“”” “”“” ” “”“”“”“” “”“”“”“”“”” ” “”“”“”“” “”” “”“”“” “”” “”“”“”“”” “”” “” “”“”“”” “”“”“”” “”“” “”“”“”“”” “”“”” “”“”“”“”“” “”“”” “”“”“” “”” “”“” “”“”“” “”“”“”” “”“”“”“”“”“”“”” “”“”“” “” ” “”“”“”“”“”“”“”“”“” ” “”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”” “”“” “” ” “”“”“”“”“”“”“”” “” “”“”“”“” “”“”” “”“” “”” “”“”“”“”“”“”” “” ” “”“”“”“”“”“”“” “” “”“”“”“”“”” “”” “”“”“”“”“” ” “”“”“”“”“”“”“”“”“”“”” “”“”“” “”“”“”“”“”“”“”” “”” ” “”“” ” “”“”“”“”“”“”“”“”“”“”“”“”“” “”“”” “”“” “”“”“”“”“”“”” ” “” “”“”“” “”” “” “” “” “” “”“”“” ” “”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” ” “”“”” “”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”” “”“” “” ” “”“”“”“”“”” “” “”“”“”” “”“”“”“”“”” “”” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “”“”“”“”“”“”” “” “” 12
Input Success Failure 14
Success DB g Lo e te da up at id al V Failure 15
Demo “”“”“” ” “”“”“” “”“”” “”“”“”“”“”“”“”“”“” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “!”“”“”“”“”“”“”“”“”“”“”” “” ” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”” “”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“” “”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “” “” |””“”“”“” “”“”“” ” “”“”“” “”“”” “”“”“”“”“”“”“”“”“” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “!”“”“”“”“”“”“”“”“”“”“”” “” ” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”” “”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“” “”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “” |””“”“”“”“”“”“”“” |””“”“”“”“”“”” |””“”“”“” | |””“”“”“” | |””“”“”“”“”“”“”“”“”“” | |””“”“”“”“”“”“”“”” | |””“”“”“”“”“”“”” |””“”“”“”“”“”” |””“”“”“” |””“”“”“”“”” |””“” | |””“”“”“”“” | |””“”“”“”“” |””“”“”“”“” |””“”“”“”“”“”” |””“”” | |””“”“”“”” | |””“”“”“”“”“” | |””“”“”“” “” 16
YAGNI…? You Ain’t Gonna Need It… ? 17
Typescript Self-Documenting Code Exhaustive Failure Checking Composing Can Be Tricky 18
Success DB g Lo e te da up at id al V Failure 19
Input Success Also input? Failure 20
Bypass 21
Demo “”“”“” ” “”“”“” “”“”” “”“”“”“”“”“”“”“”“” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “!”“”“”“”“”“”“”“”“”“”“”” “” ” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”” “”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“” “”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “” “” |””“”“”“” “”“”“” ” “”“”“” “”“”” “”“”“”“”“”“”“”“”“” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “!”“”“”“”“”“”“”“”“”“”“”” “” ” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”” “”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“” “”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “” |””“”“”“”“”“”“”“” |””“”“”“”“”“”” |””“”“”“” | |””“”“”“” | |””“”“”“”“”“”“”“”“”“” | |””“”“”“”“”“”“”“”” | |””“”“”“”“”“”“”” |””“”“”“”“”“”” |””“”“”“” |””“”“”“”“”” |””“” | |””“”“”“”“” | |””“”“”“”“” |””“”“”“”“” |””“”“”“”“”“”” |””“”” | |””“”“”“”” | |””“”“”“”“”“” | |””“”“”“” “” 22
Promise.resolve() YAGNI…? You Ain’t Gonna Need It… ? 23
Promises Limited API 24
Promises API Methods Combinators Promise#then Promise.race Promise#catch Promise.allSettled Promise# nally Promise.all Promise.any fi 25
Promises Limited API Domain ✖ Panic 26
Errors Domain Expected Panic Unhandleable t s u ha x E o N s k c e h c e v i INVALID INPUT DATA OUT OF MEMORY EXTERNAL SYSTEM UNREACHABLE DIVIDE BY ZERO 27
Fp-ts https://github.com/gcanti/fp-ts 28
””“”” “”“”“”“”“” ” “”“”“”“” “”“”“”“” “”“”“”“”” “” “”“”“”” “” “”“”“”“”“”“” “” “”” “”” “”“”” “”“”” “”“”“”“”“”“”“” “”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“” “”“”“”“”” “”“”“”“”” “”“”“” “”“”“”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“” “”” Left “”“”” “”“”“” “”“”“”“” ” “” “” ” “”“”” “”“”” ” “”“”“”“”“”” “”“”” “”“” ” “”“”“”“” “”“”“”“”“”” ” “”“”“”“” “”” “”“”“” “”” “”“”“”“”” “”” “” “”“”“”” “”“”“”” “”“” “”“”“”“”” “”“”” “”“”“”“”“” “”“”” “”“”“” “”” “”“” “”“”“” “”“”“”” “”“”“”“”“”“”“”” “”“”“” “” ” “”“”“”“”“”“”“”“”“” ” “”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”” “”“” “” ” “”“”“”“”“”“”“”” “” “”“”“”“” “”“”” “”“” “”” “”“”“”“”“”“”” “” ” “”“”“”“”“”“”“” “” “”“”“”“”“”” “”” “”“”“”“”“” ” “”“”“”“”“”“”“”“”“”“”” “”“”“” “”“”“”“”“”“”“”” “”” ” “”“” ” “”“”“”“”“”“”“”“”“”“”“”“”“” “”“”” “”“” “”“”“”“”“”“”” ” “” “”“”“” “”” “” “” “” “” “”“”“” ” “”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” ” “”“”” “”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”” “”“” “” ” “”“”“”“”“”” “” “”“”“”” “”“”“”“”“”” “”” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “”“”“”“”“”“”” “” “” Right Either<S, T> = | Left<S> | Right<T> Result<T, S> = | Success<T> | Failure<S> Failure Success 29
Demo 30
31
“You Have To Master A New Skill, But You’re Avoiding It Because You Know You’ll Be Bad At It When You First Do It.”
Railway Oriented TypeScript @robinpokorny