TypeScript for skeptics

By Nick Ribal, November 2018

The ugly duckling: TypeScript’s past, present and future

In front-end terms, TypeScript has been around for a while. After a decade in front-end, I ignor hype for about a year to see whether THE-NEXT-BEST-THING™ gains momentum and real-world adoption.

TypeScript was no exception. The fact it looked like another ugly attempt to put the “Java” back into “JavaScript” made me skeptical and reluctant to try typescript@1. It smelled too corporate and looked as attractive as office fluorescent lights…

Java logo with “JavaScript” erroneously written below it

But over time, and especially after typescript@2’s release, lots of smart folks began adopting and praising the language. Several trusted friends assured me that TypeScript is just “safer JavaScript”. In the spectrum from modern dynamic and functional languages to classical OOP, TypeScript’s gradual and structural typing, as well as type inference placed it closer to the former, rather than latter category.

The thing that finally changed my mind was the reassurance that I won’t need to change my chosen coding style (functional programming) and could still benefit from type safety.

In addition, TypeScript steadily evolves at a surprising pace: gaining features, library and tooling support, resulting in ever greater adoption. It’s not an underdog, nor is it reserved for dull, corporate dashboards. Especially nowadays, with typescript@3 additions, it’s time to give it a chance!

Taming the beast: you control strictness

Friendly dog overlooking fence with scary “BEWARE OF DOG” sign

TypeScript’s gradual typing and flexible configuration allows you to be as lenient or strict as necessary. Tuning compiler flags enables gradual conversion of legacy applications, as well as uncompromising strictness for new projects.

I believe in strict and automatically enforceable coding standards via static analysis tooling and mandatory code reviews. I’ve been teaching and preaching for clean code, encouraging and enforcing a tight feedback loop for teams I lead and clients for years.

Any tool, which can catch mistakes early and shorten the feedback loop deserves my attention. Immediate feedback from tests and static analysis reduces wasted time due to wrong assumptions and errors, making TypeScript a natural fit and the next logical step.

So when I began leading a long term, remote, greenfield project for a major client in the financial sector with uncompromising quality requirements – TypeScript fit like a glove. Handling money and implementing complex business logic make TypeScript’s features very appealing. I could test TypeScript at its full potential, as strict as possible.

“There ain’t no such thing as a free lunch.”

I’ll be frank: TypeScript has plenty of strings attached. You must invest in finding, setting up, configuring and integrating TypeScript compatible tooling and packages. The compiler can be too strict, the linter needs tweaking and you gotta jump through hoops to make tooling work for you.

A lack of alternatives for Babel plugins is an example: for better or worse, they are common and even mandatory for certain packages’ core features. TypeScript’s equivalent, “transforms”, are scarce to non-existent. So can you use a nice package like Emotion with TypeScript?

Grumpy cat says “NO.”

 

And you’ll face bugs in popular packages, missing types and breaking changes.

Then there’s the language itself: TypeScript is easy to read but is hard to write (unless you’re experienced with strongly typed programming). Assuming you’re not writing Java style but are typing the dynamic, expressive and flexible JavaScript you know and love – keeping the program sound is HARD. It is arduous work, it can be too verbose, and some error messages are vague and confusing.

Writing strict TypeScript requires considerably more work, compared to JavaScript’s naive CTRL+S, as soon as you think you’re done. Is it even worth it?

Yes, definitely!

Magic happens as soon as the compiler is satisfied: BOOM! Everything Just Works™. NO RUNTIME ERRORS. None, nada, practically ever!

Shia Labeouf MAGIC meme
Shia Labeouf MAGIC meme

Unless your logic is wrong (which no compiler can catch), JavaScript’s tiresome “save, run, fix, save, run, troubleshoot, fix, save, repeat… ad nauseam” cycle breaks in favor of almost boring predictability. Hard to believe at first, you keep running the program expecting it to fail – but when a strictly typed program compiles, things work!

Obviously, anything you can’t type still has to be handled: API calls, responses, missing permissions, timeouts, JSON.parse(), etc. But you actually focus on those, instead of your program’s basic (in)ability to run.

“But wait, there’s more!”

Compared to JavaScript, it’s amazing just how well TypeScript prevents bugs and detects edge cases. When the compiler uncovers a codepath you’ve missed, which would’ve inevitably been a major bug, the value of the language really sinks in.

Refactoring and autocompletion are awesome: renaming, refactoring and moving entities between files, modules and classes are built-in. Because TypeScript is developed in tandem with its language service (which is used by any TypeScript compatible editor), you get IDE capabilities in any editor – without a heavyweight IDE.

Renaming a React prop and it_s interface in Sublime (screen capture)
Renaming a React prop and it’s interface in Sublime (screen capture)

Evergreen documentation is another benefit: unlike comments and (non autogenerated) docs, type annotations – by their very definition – cannot rot, lie or get out of sync with code. They’re a clear and enforced contract between interdependent program parts.

A strict TypeScript codebase builds confidence in your program’s correctness, allows you to reason more clearly about it, and guarantees up-to-date documentation of its parts and their relations. TypeScript’s inherent traits compose elegantly, allowing and empowering developers to refactor and modify a program as it grows and evolves in new, unpredictable ways, as software usually does.

TL;DR: is TypeScript suitable for a given project?

“One does not simply TL;DR engineering trade-offs” meme

As with all engineering decisions, you manage priorities and trade-offs.

In my view, TypeScript is less suitable for quick, temporary or exploratory work. Typically, it won’t help with incomplete ideas (which you want to test through code), quick POC’s, monkey patches, hacks or just playing with novel APIs or concepts. It’ll get in your way, distract, interfere and hinder your progress.

It’s noteworthy that several of my colleagues and friends disagree and attested to TypeScript’s helpfulness even in casual tasks!

When you’re investing in a long-term project, large or distributed teams, TypeScript is great! If reliability, maintainability, documentation and correctness are the baseline requirements, then TypeScript is a solid choice which will benefit you and your team in your goal to deliver a better product to end users.

Stay (type) safe!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: