1. TypeScript is a separate skill to learn and comes with all the heartaches and headaches of learning any new thing. For most of us, it will take time and persistence - and that's okay!
2. Typing libraries is a different skill set than just using types, and TypeScript + React is yet another skill set to learn. Look for specific examples and documentation in the layer you're on, not just generic TypeScript content.
A problem I kept running into was that a lot of the tutorials and documentation I saw assumed that you were writing an application. However, what I found that typing a piece of library code required significantly more complicated types - many things needed to be generic or much more flexible than the strong opinions you can hold in application code. You're forced to learn about generics, conditional types, and a litany of other TypeScript functionality you probably don't need in most applications. Find examples that match the work you're doing.
3. Abandon the official docs ASAP.
The official docs thankfully got an update right before I published this and is significantly easier to navigate, but still pales in comparison to a litany of other resources that will help you get started faster. If you're brand new to types, I'd highly advise you check out one of these two resources. Basarat's guide to TypeScript is a great all-encompassing walkthrough of what types even are, and then Shawn Wang's React TypeScript cheatsheet will kickstart your learnings of how to use this with React.
- TypeScript in General: https://basarat.gitbook.io/typescript/
- TypeScript with React: https://github.com/typescript-cheatsheets/react-typescript-cheatsheet
4. Learn and leverage utility types, and don't be afraid to explore type helper libraries.
When I first started, I didn't spend too much time thinking about how to use helper methods like
Pick, Omit, Required. To make a comparison to Sass, discovering and using these methods is like finding nested media queries for the first time. Instead of all this inane repeated code, you're now just cooly relying on things you've already defined; your future self will love you when you have to refactor your code and only need to change things once.
However, sometimes you need even more power - and luckily, there are a few packages out there that the community has built to ease you on your way. Exploring these packages gives is a helpful reminder about all the things TypeScript can do, once you've mastered the syntax.
5. If it's too complicated to type, you might be running into a design error with your API.
There comes the point where you're going to throw your hands in the air and declare something impossible to type. There are too many relationships between different sets of data, the syntax is too complicated, the generics aren't working out, or some other problem in that vein.
When this happens (and it will), I'd tell my younger self to step back and reexamine the design of the function I'm writing. If it's too hard for me to accurately describe what a type is for a function, it's probably too hard for someone else trying to use the same function to intuitively know what it means.
This advice comes with a grain of salt - sometimes the issue is that you don't know enough about TypeScript yet (often, these complex types require advanced knowledge around conditional types or something similar), which was definitely the case for my first few months. However, as you continue to explore Typescript, you'll get a better sense of when it's your lack of knowledge, or when it's your API design.
6. Type guards are just functions that return true/false for an expression
This might have been obvious to other people, but for me, the words "type guard" seemed a little mysterious. Why would I intentionally run an extra function to check for types when I'm already telling TypeScript what I'm doing? The answer is two-fold.
The first is that, while you might be typing everything correctly, TypeScript can only check things that you write. Unless you generate types for external data (like your APIs), those requests can come in any form and break your application at runtime. If you have a type guard in there, you can at least capture the error and try to gracefully handle it in your UI.
The second is that type guards allow you to narrow types inside a function. Sometimes you'll pass a function an item that could be a variety of different types (generally through a discriminated union), and your function won't know which one of those types the item is. With a type guard, you can tell TypeScript which one of those items it is.
7. Generics are great and will make your components flexible. But also, ignore that terrible convention of using single letter generics.
Finally, I wish my younger self was not so scared of generics when I was starting out. Part of this was that I would read documentation and tutorials that looked something like
function Foo(S, T extends keyof S) and it looked like absolute gibberish to me.
After some time, though, it dawned on me that generics are just a mashup of variables and function arguments, transmogrified into a type system. Like variables, they can be reused after they're defined to refer to their value. And like function arguments, your users are passing them in expecting that they'll get used to help compute something else down the line. Like a function argument, you can set a default generic to help your user, and because this is types and not actual values, you can also require a specific shape.
Oh - and younger me? - remember that setting a default generic does not set a type shape, you still need to extend a type to do that.
Whew, that was a lot!
Thanks all for reading! If you want to hear me and Una Kravets talk about this blog post while I was writing it, give us a listen on toolsday. If you have any questions or thoughts, feel free to ping me at @chrisdhanaraj on Twitter or drop a comment below.
If you were like me, then some of the words I've used in this post might not have made sense. I've compiled a list of the TypeScript specific words that I referenced and some links to better understand them.