paypal-scripts now supports TypeScript as well as JavaScript

Kent C. Dodds
Jan 21, 2019 · 9 min read

What happened that made TypeScript viable for me and worth migrating paypal-scripts for.

Note: There was a lot of misunderstanding about this post so I want to make it clear that most of PayPal still uses JavaScript and this post is just to announce that PayPal engineers can now very easily choose between TypeScript and JavaScript for their projects without fiddling around with tooling.

NOTE: This is a cross-post from my newsletter. I publish each email two weeks after it’s sent. Subscribe to get more content like this earlier right in your inbox! 💌

… here it is!

At PayPal, I work on a tool called paypal-scripts which is a toolkit (like react-scripts from create-react-app, or angular-cli, or ember-cli or … etc…). I’ve written about it before. The idea is that it encapsulates all the tools common to PayPal applications and published modules. The goal being taking the huge list of devDependencies in the package.json and all the config files and reducing that down to one entry in the devDependencies. And because all the config lives within a single opinionated package, keeping things updated is a matter of updating one dependency (paypal-scripts) which typically does not need to make breaking changes. So you just keep that one dep updated and you go back to building your app.

For the last year, people at PayPal have opted-into adopting paypal-scripts. At PayPal, you create a new app by clicking a few buttons in a web UI which will create your GitHub (enterprise) repo and setup CI, deploys etc. etc. The GitHub repo it creates for you is based on a repo called the “sample-app.” Just last week, my PR to update it to use paypal-scripts was merged. This means that every new applications at PayPal will get their start with modern technology and tools that they don’t have to worry about keeping up to date. They will also be statically typed with TypeScript and tested with Jest.

Honestly, this is my Magnum Opus of my career. I honestly don’t think I’ll be able to top this at PayPal. The impact of this project is huge and I’m so grateful to PayPal for giving me the opportunity to work on something so huge.

/you shakes me awake

Right ok, back to the TypeScript thing.

So halfway through December, I was working on getting the sample-app updated to use paypal-scripts. I was also working on pp-react which is a (WIP) reusable component library for PayPal projects (buttons, modals, typography, etc.). Because paypal-scripts supports publishable modules, I was using paypal-scripts to build pp-react. A month ago, paypal-scripts shipped with support for FlowType. Support for FlowType was really easy to add to paypal-scripts thanks to Babel.

On December 12th, as I was working on Flow for both pp-react and the new sample-app, I finally got fed up with Flow (more on this later) and made a snap decision. I sent this to my co-worker Jamund Ferguson:

What would you say if I tried to make the sample app use TypeScript

To which he responded with:

YES DO IT

And so I took a poll of the #paypal-scripts slack channel and 100% of respondents said they wanted the change. That was good enough for me and I started the work on it. About a week later, I had totally migrated paypal-scripts from supporting Flow to supporting TypeScript (most of that time was making all the tools recognize .ts and .tsx files 🙄 and allowing paypal-scripts to dogfood itself which is kinda tricky 🐶). Then a few days of updating my sample-app PR to use the new and improved paypal-scripts and move from .js to .tsx and .ts files. Then we had Christmas break 🎄 and the week we got back after the new year 🎆, it was merged and now every new project starts off with modern tools that will stay updated by default and will be statically typed with TypeScript.

NOTE: Of course once people create their app, they are free to do whatever they like with it, they can remove all the code and switch to Elm or whatever and that’s totally fine. But most projects will stick with what they’re given thanks to the default effect.

What took took me so long?

Here are the things that held me back from TypeScript:

Abandoning my existing toolchain of Babel and ESLint

One thing I like about Flow is that all I need to do to adopt it is:

  1. Add the babel preset for the syntax
  2. Add // @flow to the top of every file I want to typecheck (there’s an eslint plugin to make sure you do)
  3. Add a script to run flow on the codebase to do typechecking

I really like that typechecking (via Flow) and code building (via babel, webpack, or rollup) are separate. I didn’t want to hand my life over to TypeScript, particularly if it wouldn’t understand my custom babel plugins anyway. Particularly because I had flow which was “good enough” (read more about this below).

From there, everything continues to work like normal. Well, thanks to Babel 7 (and more specifically @babel/preset-typescript), we can keep our tools and get most of TypeScript as well. The biggest trick is making tools accept the .ts and .tsx extensions, but thankfully that’s a solvable problem.

Forcing contributors to have to know TypeScript to contribute

It’s a pretty poor argument honestly and with more and more people learning TypeScript I think I’ll probably be authoring my open source packages in TypeScript in the future.

Flow Type Inference

With Flow you’ll be adding types to make errors nicer, not to uncover them.

This is absolutely true. Today, Flow has better type inference than TypeScript and that comforted me.

Flow is from Facebook just like React

TypeScript Zealots 😬

But I’ve had interactions with people who would call you crazy or stupid for not using or understanding TypeScript or using anything else. That attitude is free of empathy and pretty snobbish. That is not the kind of community of which I want to be a part. I mean, it’s great to be enthusiastic about your technology choice, but it can go too far when you start insulting other people who have made different choices.

This is still a concern that I have. Hopefully we can work together to improve the empathy of the community.

What was so wrong with Flow?

The regular unreliability of flow was what finally made me give up on it. The editor plugins only sometimes worked (full disclosure, I never tried Nuclide and maybe my life would’ve been different if I had, but I tried flow in Atom and VSCode) and I would get issues like the one all the time. It was incredibly frustrating because I could never trust my type checker. There were other issues as well.

When I saw this tweet thread from Jamie Kyle back in November, it really resonated with me and my experience. I honestly couldn’t stop thinking that I should really give TypeScript a solid shake. So I finally did and I’m glad that I did!

Other questions and answers…

Why not TSLint?

Oh, and it looks like the TypeScript team is investing in ESLint over TSLint so I guess I’m making the right bet :)

Why not Reason?

It may be time to try @typescriptlang!!!

To which I responded:

Honestly, if I’m going to make a change, it’ll be @reasonml :P

I’ve often said that I’d switch to Reason before switching to TypeScript. A big reason for this was what I mentioned above about having to abandon my existing tools. But because I wasn’t forced to face that, TypeScript was more attractive. I’m still excited by Reason, but switching to Reason would have been a HUGE jump for lots of people at PayPal and while I think they’re super smart and capable people, I think they’ll be more productive using TypeScript than trying to learn a new language.

What would have happened if I’d gone with Reason is I’d probably never have gotten my PR merged into the sample-app. It’s one thing to get buy-in from folks about using something that’s basically JavaScript with types (especially when there’s basically no config to maintain), but it’s an entirely different conversation to convince them to use an entirely different language and ecosystem (no matter how good that language’s inter-op with npm/JS is).

Thanks

Seriously, twitter people helped me a LOT as I was making the adjustment, so thank you! I am going to try to make stuff to help people learn TypeScript. Here’s one thing I made recently based on stuff I learned from twitter folks: TypeScript: Why you have to add types even if you handle the undefined case.

Conclusion

👋 Hi! I’m Kent C. Dodds. I work at PayPal as a full stack JavaScript engineer. I represent PayPal on the TC39. I’m actively involved in the open source community. I’m the creator of TestingJavaScript.com and I’m an instructor on egghead.io and Frontend Masters. I’m also a Google Developer Expert. I’m happily married and the father of four kids. I like my family, code, JavaScript, and React.

PayPal Engineering

The PayPal Engineering Blog

Kent C. Dodds

Written by

Making software development more accessible · Husband, Father, Latter-day Saint, Teacher, OSS, GDE, @TC39 · @PayPalEng @eggheadio @FrontendMasters · #JS

PayPal Engineering

The PayPal Engineering Blog

Kent C. Dodds

Written by

Making software development more accessible · Husband, Father, Latter-day Saint, Teacher, OSS, GDE, @TC39 · @PayPalEng @eggheadio @FrontendMasters · #JS

PayPal Engineering

The PayPal Engineering Blog

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store