TypeScript Fundamentals, v3 Wrapping Up
Transcript from the "Wrapping Up" Lesson
>> Just to recap all the ground that we've covered today. We started with a little introduction to TypeScript, and compiled our first TypeScript programmer, saw the compiled result. We changed our module types. We changed our language level, we saw the difference in output. We talked about variables, values, objects, and arrays.
[00:00:21] A little bit about tuples, and we learned about type annotations, and index signatures, ways to define the types of collections of data. Then we moved on to talk a little bit about theory for type systems. Different ways of categorizing type systems, and a little bit of set theory to describe union and intersection types.
[00:00:44] We gave our types names, using interfaces and type aliases, and defined some recursive types that we can use for any JSON value. Then, after talking about functions and classes, my favorite part about functions is those multiple function heads. We talked about top and bottom types. These are those extreme types that can be anything at all or nothing.
[00:01:12] And within extreme types, we talked about that cool example for exhaustive conditionals, where you can make sure that you handle every possible scenario. And you kind of end up with no pieces of the pie leftover, absolutely every scenario handled. And you have compiled time enforcement of that, which makes it really easy as you introduce new possibilities into your code base, they're caught for you.
[00:01:38] We built some user defined type guards and learned assertion type guards, and conditional type guards. Talked a little bit about nullish values, talked about generics, built up a little standard library for working with dictionaries. And then finally, scopes and constraints for type parameters. That is a lot of ground to cover.
[00:02:00] And that will put you in a great position for taking intermediate TypeScript, where we're going to dig even deeper into these topics. And now that we've conquered generics, we're ready to go with some even cooler concepts. Thanks so much for coming today and hope you had a good time.
[00:02:19] I hope you enjoyed the course.
>> So back to the user defined type course, do you remember that CarLike example?
>> The car, sorry, let me go back to that. Type guards, and you wanted CarLike, the assertion ones or the is one?
>> It doesn't matter, I was wondering is there some sort of a more deliberate wave.
[00:02:48] It's shaking for your object type, especially that something I believe you'll find that most. It's a chaser, right, you came across it more than you should.
>> Yeah, so you're wondering are there, I think you're saying this seems like a very low-level API. Are there higher level more declarative ways to inspect an object to figure out what types are on it?
>> Yes, maybe some sort of a utility that's been around.
>> There are those utilities, and they do exist. Here's the trick though. Type checking at runtime is not free. And especially, if you're running this code on a very hot path, like a performance sensitive path. You may not want to be doing too much with a mystery library that may be doing some heavy things.
[00:03:45] It's kind of tricky to solve in the general case, but they do exist. I'm just not prepared to endorse any particular one. Cuz I'm really looking for simple and performance for things like this.
>> So what are your advice exactly when it comes to this? Cuz I see a lot of repetitions in place.
>> Yes. So my advice-
>> [INAUDIBLE] Is start to define a couple of fives and add some assertions, and type guard too is gonna be like a massive chunk.
>> It does get a bit messy. My advice if you're at all able to do this is to push this problem into your API layer, where effectively every one of your, We're talking about values discovered at runtime really, that's often where you're gonna be using type guards.
[00:04:44] That discriminated union thing where, I see that there's a property called kind, and I see that there's this label on it. Once you can do that and you can say, well, if I see this thing here, this c tag on it, I know that the whole thing, I know what it's gonna be.
[00:05:02] That's a powerful idea. GraphQL has some support around this as well, where based on the query you make and some things that you can do at build time. You can have some pretty strong guarantees given that it sort of one central definition of a type that ends up both in your client and server code.
[00:05:21] That's also common approach. So anything where you have a well structured convention, this kind of code ends up being a lot cleaner, in that you have a few type guards that are heavily reused. And they sort of end up being nested, right? You could have a type guard that's, is this a single record or a collection?
[00:05:41] Once you figure that out, okay, well, what's the type of this item in the collection? And they sort of stack up in that way. Does that make sense?
>> Yeah, thank you.
>> There is one more I wanna leave you with, it's my favorite type guard of all time.
[00:06:02] It's this one. This will be an intermediate course for sure. We don't have to make it the assert. So, now we're mixing two things, right? It's a type guard that is generic. So, in this case, what this lets us do let, Something like that. So you could say if (isdefined(x)).
[00:07:01] And you can see here, it's a number. So you can start to make these type guards, involve type params with these type guards. And effectively what we're doing is we're saying, we're peeling away the undefined. This is why I don't wanna use the definite assertion operator. It's because I can write this, and it's something that will actually do the checking for me.
[00:07:23] And then it'll let me throw a meaningful error instead of cannot find too fixed on undefined, some weird, just letting it explode wherever it's gonna explode. But kind of getting clever with these things is is often time well spent.