Functional programming in TypeScript: the abstractions I actually use and the ones I dropped
There's a specific moment I recognize in almost every developer who arrives at TypeScript from a typed-language background: you open the fp-ts docs, you see pipe, Option, TaskEither, ReaderTaskEither, and you think "this is what I was missing." The type checker backs you up. The API is beautiful. The theory is solid.
Three weeks later, the PR has 800 lines of changes and a comment from a teammate that says: "what does fold do here?"
My thesis is this: functional patterns have real value in TypeScript, but full fp-ts adoption has an onboarding cost that almost nobody mentions when evangelizing the library. The criterion I ended up with — after evaluating full adoption and rejecting it — is: adopt the patterns, not the library, unless the entire team is aligned and willing to sustain it.
I'm not anti-FP. I use pipe, I have a homegrown Result type, and I think in pure functions when I can. But there's a difference between writing functional code and adopting a framework of mathematical categories in a collaborative project.






