Seven lessons I wish I learned earlier about Typescript
Tags: typescript, javascript, codenewbie
Published: 2020-08-15 23:50:28

By now, you may have seen the blog posts about TypeScript's ascendance. It came second in languages developer's love in Stack Overflow's [annual developer poll](https://stackoverflow.blog/2020/05/27/2020-stack-overflow-developer-survey-results/), spiked to the *seventh* most used language on [Github](https://octoverse.github.com/) in just two years, and has seen a steady increase in Google trends while JavaScript stays more or less stagnant. With all that, it's maybe not a surprise that where I work ([Netflix Studios - we're hiring!](https://jobs.netflix.com/teams/studio-technologies)) made an announcement last year that all our official UI libraries would be in TypeScript going forward.

The only problem was, well, I was writing one of those libraries. And I had never used TypeScript before, much less *any* typed language at all (or... actually, any other language beyond HTML / CSS / JavaScript). So for the last year, I've been struggling through concepts like "generics" or "type inference" and wanted to roll up a list of things that I wish I knew before I started.

**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!**

Something lost in all the euphoric tweets about how TypeScript will save JavaScript is simply how *hard* it is for someone new to pick up. I have a gut feel that a lot of the folks proclaiming how TypeScript made Javascript makes sense are coming from another typed language. 

I, on the other hand, simply didn't even know the vocabulary of typed languages at all, much less TypeScript. It was incredibly frustrating to just try to sit there and google the problem I was having (and then add "typescript" to the keyword list) and not even know how to describe the problem I was having or what word to use. This frustration especially hit hard when I knew I could solve the problem with just JavaScript, but couldn't figure it out with types. It took me six months before I settled into a headspace that recognized how difficult this was and stopped beating myself up about it.

**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/](https://basarat.gitbook.io/typescript/)
- TypeScript with React: [https://github.com/typescript-cheatsheets/react-typescript-cheatsheet](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](https://twitter.com/una) talk about this blog post while I was writing it, give us a listen on [toolsday](https://spec.fm/podcasts/toolsday/gH_xhl5d). If you have any questions or thoughts, feel free to ping me at @chrisdhanaraj on Twitter or drop a comment below.

#### **Glossary**
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.

1. Conditional Types - [Conditional Types in TypeScript](https://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/)

2. Generics - [TypeScript Generics Explained](https://medium.com/@rossbulat/typescript-generics-explained-15c6493b510f)

3. Utility Types - [List of out of the box Utility Types](https://www.typescriptlang.org/docs/handbook/utility-types.html)

4. Typeguards - [Make types real - the typeguard functions](https://medium.com/@wittydeveloper/typescript-make-types-real-the-type-guard-functions-814364e8dbe3)