5 Inconvenient Truths about TypeScript
I’m writing books about TypeScript and I do workshops and trainings online and in-house. Every time I meet a new group of developers there are some TypeScript facts that they need to be confronted with:
TypeScript’s type system fully embraces structural typing – for good reason – and this, combined with the fact that types are just meta information that lie on top of existing code can be alienating to a lot of people who expect a quick transition from one language to the other.
2. TypeScript adds complexity #
Still, TypeScript adds a layer of complexity to your project that you need to be aware of. And I’m not only talking about types and the complex, advanced features like Conditional Typing. I’m talking about all the knobs, switches, and integrations that TypeScript brings to the table to be compatible with fricking everything! Running TypeScript in Deno? Check. Node? Of course! Internet Explorer 5? We got you. With Babel? Sure! Babel and Webpack? Yes. Esbuild? You name it! With my seven-year-old charting library? Turn off
noImplicitAny, then it’ll work! A mix between UMD, AMD, and CommonJS? Hah, sure! JSX? Yup. TSX? All clear! TSX in React 18? Uh-huh! 17? It does!
You get the idea. The TypeScript compiler is configured through TSConfig, a huge JSON file with lots of possibilities to tailor TypeScript to your needs. There are so many different configuration options that it gets really hard to tell which rules are now actually applied. And once you overcome this configuration extravaganza, you can start looking into all the trade-offs TypeScript is doing for you so you get safe code.
TypeScript is a complex matter.
3. TypeScript is not type-safe #
This might be a surprise for many, but TypeScript actually isn’t type-safe. TypeScript’s type-checking works really well in what I like to call the “inner type world” of your application. That part where you defined your types, the operations on them, and their flow throughout your program. Here, everything that should work together will work together, everything that doesn’t will cause red squiggly lines and compiler errors.
But there’s stuff at the edges. If you leave the inner world of type safety and need to reach out for basically any IO. User input. File access. Fetching data over the internet. Here TypeScript has no clue what the types are about and needs to rely on what you tell it. You need to make type annotations, type assertions, or huge control flow checks to give TypeScript a hint of what to expect. And those measurements are just as good as you are. in TypeScript, you have the ability to change a type to something else at any time. You can override from a broad type that allows for many values but is less specific to a narrow type that allows for fewer values but gives more information at any time, sometimes without even noticing. And there are situations, especially with APIs that return
any, where you might annotate something entirely different than you get back.
And nothing keeps you from it.
Not only that, but TypeScript has a few corner cases where it trades type safety for productivity. And those are the scenarios that can really bite you!
The fun thing about is that TypeScript always had a strict non-goal to be provably type-safe. It’s all about making developers productive. It should not get in the way, but help you find the right information fast. Another trade-off.
4. TypeScript comes in many flavors #
Have you decided on whether to use types or interfaces? Const enums or regular enums? Do you infer or annotate? Do you care? What’s your TypeScript flavor?
It’s almost like in C++, where teams always need to decide on a subset of the language to manage complexity. TypeScript asks the same from you.
5. It’s still worth it #
I’ve been doing TypeScript for 6 years and I have written two books on that topic. I do workshops in-house for teams and publicly through organizations like Smashing Magazine. Today, I showed you a lot of examples where TypeScript is not all glitter and glory.
Still. TypeScript is totally worth it. Understand the language, understand its trade-offs and caveats, and understand what it brings to your table. Then you can fully embrace the power of TypeScript as a type system and programming language.
And you know what, then it becomes fun!
TypeScript is here to make your life and the life of your team easier. And it succeeds! Try going back to a project after 6 months of time and try to recreate the mental model you had from your application. Or look at well-crafted types that tell you a story. I’d always go for TypeScript.