Production-Grade TypeScript TypeScript in Apps vs Libraries
Transcript from the "TypeScript in Apps vs Libraries" Lesson
>> So the last thing I wanna talk about before we jump in and start writing some code is the difference between app and library concerns. So we're on section three of the notes now. First, I wanna dispel a couple myths here. They may seem true at first, but it is my experience that When TypeScript is used for a non trivial app, these things do not really hold up.
[00:00:26] So, first is the idea that TypeScript is a cure all for runtime errors. Like you will not have errors at runtime anymore because you use TypeScript. False. So all TypeScript does is it catches a subset of errors that have to do with type checking, and it surfaces them to you earlier.
[00:00:46] Particularly because you can get unexpected API responses. Maybe a user's attempting to run your app in a browser that you didn't officially aim to support. Maybe they're trying to use IE11 and you built for chrome, right? These are the kinds of things that will absolutely cause runtime errors and TypeScript can't do a thing about them.
[00:01:12] In fact, TypeScript has no role whatsoever in your app at runtime. It disappears after you built. So I want to dispel that, because it's important to understand what TypeScript can't do. Just as you wanna understand what it can do. The second myth I wanted to dispel is the idea that TypeScript makes your code much faster.
[00:01:36] Now, it does encourage practices that will reduce the likelihood of modern browsers, deoptimizing your code. But I want you to listen to how many qualifiers I added to that statement. So a modern browser, when it takes your app might pick 12 functions and optimize the most common functions that are used.
[00:02:05] So if you're using something like React, almost all of those are going to be things in the React library, not your app code that get optimized, right, React create class, right? Invoke that all the time or create element. Those are what get optimized. Now, TypeScript will encourage you to write code that is less likely to ruin that, but it's not going to make the rest of your code, the vast majority of it that is not effectively converted to assembly and reused.
[00:03:06] That is a great way to set expectations way too high, and particularly the business side of your engineering company, that's a great way to promise too much something you can't possibly deliver on. Alright, so now that we get that out of the way, let's talk about things that are commonly concerns that you might look for common benefits.
[00:03:33] Regardless of whether you're building a library or an app, you probably have these. So you want an improved developer experience sorry. You want an improved developer experience, tooltips, autocompletes things like that TypeScript does a great job with this. TypeScript reduces the need to context switch. So the fact that information is surface to you inlined into your authoring process, right?
[00:04:02] The autocomplete, the misuse of certain functions, right where you're not passing in the right arguments. That saves you from having to sort of drill into all these other files and figure out how things work by reading the source code. And it allows you to maintain your focus on what you're working on.
[00:04:21] This is probably the most important one for me. It's a little subtle, but it's extremely powerful micro rigor that adds up to macro benefits. What that means is at a large scale, there's just way too much code for any person to keep in their mind and to keep track of and to deeply understand all the little caveats, you cannot possibly master all of that at once.
[00:05:12] It allows you to sort of make sure that all of the building blocks work well individually. And you see benefits across an extremely large code base, where all of that adds up to a lot of assurance you have that these things fit together the way that they're meant to fit together.
[00:05:30] I think that this would be flat out impossible without this type of information. Eventually, you're gonna lose track of how all these blocks work. So, the idea of having more formalized and stable contracts between things. This is important for libraries where you know when things are changing and you can have discussions about the shape that change should take as opposed to just tacking on one more function one more method.
[00:06:04] And that's how you end up with libraries that feel like they were half written by one person and half another. All right, I have some points here about coloring inside the lines and this effectively is different flavors of things that type checking helps to make easier, right? Incomplete refactorings if everyone here hasn't experienced TypeScript, catching an incomplete refactor, thought I updated all the places where I use this function, but there are two things that I forgot about.
[00:06:38] I think that's one of the first benefits that teams realize that they start to ramp up and tetrick. If you don't experience that often, you must use TypeScript in a very different way than I do. So let's talk about app specific concerns. And when we talk about an app.
[00:06:58] I mean, something that is a leaf level dependency. No one depends on it. No one is including an app in some other package JSON, right? So apps are usually where data happens, right? You're fetching. You're getting back in a JSON response. You're working with that. So, this is where you feel TypeScript benefits in this area.
[00:07:55] You get a better story around upgrading to accommodate braking changes. So if you go from lodash 3.to lodash 4.you can install that dependency, update your types. And immediately you have a to do list of what needs to change in order to accommodate that upgrade, you know where the incompatibilities had been introduced.
[00:08:20] For the most part, those that are type based. This is something that's felt in the library use case too, but just far less often, given that apps often have a tremendously larger number of dependencies compared to libraries. So let's talk about library specific concerns. Libraries have a public API surface and particularly if you're trying to practice semantic versioning, TypeScript lets you make sure you're honoring your guarantees.
[00:08:53] Meaning you can set up tests that represent usage of your library. And it's a lot easier when that type information is there to make sure that things continue to work the way you intended for them to work. You can communicate a public API surface. You can use things like string literal types and numeric literal types and enums to keep your users on track, right?
[00:09:22] So if you're talking about the layout library and you have different corners, you can say top left, top right, bottom left, bottom right, you don't take an arbitrary string. It's only one of those four strings that is allowed. So you can really express what you want to allow your users to do.
[00:09:39] And that's encoded into the type information. API documentation is a big deal. We're gonna see this today using some tools that you probably haven't used before, but TypeScript sort of incentivizes, great API docs. Because the information to generate API docs is the same as what you're already interested in for a great developer experience.
[00:10:07] What are my arguments? How do these tooltips look, right? You want VS code to feel great as you're working with your code. That same information can make its way into API documentation.