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.”

  • Innovation Is Combination — Greg Satell 32

Railway Oriented TypeScript @robinpokorny