# Python Tutorial: Type Hints - From Basic Annotations to Advanced Generics

## Метаданные

- **Канал:** Corey Schafer
- **YouTube:** https://www.youtube.com/watch?v=RwH2UzC2rIo
- **Дата:** 17.07.2025
- **Длительность:** 40:58
- **Просмотры:** 38,596
- **Источник:** https://ekstraktznaniy.ru/video/11699

## Описание

In this video, we'll be learning how to use Type Hints in Python to write self-documenting code, catch bugs earlier, and improve IDE completions. We'll start with basic type annotations for variables and functions, then progress to more advanced concepts like union types, type aliases, TypedDict, dataclasses, and generics. We'll also cover how to use type hints with third-party packages and discuss best practices. By the end of this video, you'll understand how to add type hints to your Python code at whatever level makes sense for your projects. Let's get started...

Type Hinting vs Checking vs Data Validation — https://youtu.be/fM4O9bModsE

✅ Support My Channel Through Patreon:
https://www.patreon.com/coreyms

✅ Become a Channel Member:
https://www.youtube.com/c/coreyms/join

✅ One-Time Contribution Through PayPal:
https://goo.gl/649HFY

✅ Cryptocurrency Donations:
Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3
Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33
Litecoi

## Транскрипт

### Segment 1 (00:00 - 05:00) []

Hey there. How's it going everybody? In this video, we're going to be learning how to use type hints in Python. So, type hints let you add type information to your Python code, which can help you write self-documenting code, catch bugs earlier, and get better IDE completions. We'll be covering the basics all the way up to some more advanced concepts like generics and type aliases. Now before we get started, I want to mention that I have a previous video that goes over the differences between type hinting, type checking, and data validation. If you don't understand those terms or the differences between them, that video might be useful to watch before this one. This video is going to focus specifically on type hinting. But it's important to understand that type hinting by itself doesn't give you type checking by default in Python. You'll specifically need a type checker in order to get feedback on your type hinted code. In this video, I'm using the My Pi extension in VS Code for type checking. If you're not using VS Code, uh you can use MYPI in the command line as well. Uh you can install it with either pip install my pi or if you're using uv like I've used in some previous videos, you can do a uvad myi and install it that way. uh or you can use uh UVX and just use that as a runoff as a one-off tool. So if I wanted to run that on my main. py script, then I can run that and uh we can see that it says uh success, no issues found uh so far, but I currently don't have uh type hinting in my file here. But like I said, I have the My Pi extension installed. So instead of running this manually, I'm going to have this problems tab pulled up here. And that should show me the My Pi errors as they appear. So, let's go ahead and get started and see how to add type hinting to our code. Now, as we go through this tutorial, you'll likely notice that we're going to go from less specific to more specific in terms of the values that we're expecting and the type hints that we're adding. And you can add these in at whatever your comfort level is. Uh, a lot of people don't use type hinting at all. Uh, so adding in very generic hints will likely save you even a little bit of frustration down the road. And as you get more and more specific, you're just expanding on the bugs that you'll catch early and the other useful things that you get from type hinting that we talked about before. But don't feel uh that you need to do the most advanced stuff right out of the gate. Think of this basically the same way that you would think about uh documentation and adding comments. Uh so it's a good thing to have some if you're not using any at all. uh and you can have as much as you want, but it is also possible to overdo it a bit. So, let's go ahead and look at some examples. So, I have this very simple script uh here that creates some users. We have a create user function here that takes a first name, last name, and an optional age, and it returns a dictionary with that user's information. And you can see down here that we're creating a couple of users and just printing them out. So let me go ahead and run that really quick. And we can see that it creates two users and prints out their information. Now this code works fine, but let's see how we can improve it with some type hints. Now let's start with the most simple type hints and that's variables. So we can add type hints to variables uh just like this. So up here where I have this string of Corey and this age um of 38, I can say that this is a string just by adding in this colon str here and I can say that this is an integer by adding this colon integer here. Now with a type checker like my pi running, it will give us errors if we try to do something that violates these types. So for example, if I try to reassign this age to um a string. So for example, I'll reassign this to a 38. Then you can see that my pi gives us a warning here and says incompatible types and assignment uh has type string uh variable has type int. So that's just how my pi works out of the box by default. uh it's assuming that if you are going to change uh some variables around, you're probably going to keep it the same type that you uh specifically said that it was. So, I'm going to go ahead and remove that. Now, to be honest, I almost never type hint variables that are obvious like this. So, we can clearly see that this one is a string and an integer just by looking at the code. Uh there are times that I think annotating a variable is useful uh such as when you want it type checked uh as it changes or if the variable is more complex like an iterable of certain types or something like that. Uh but we'll see some examples of where it is useful to do variables like this in just a bit. But for this tutorial I don't really need these simple variable examples. So I'm just going to go ahead and remove those.

### Segment 2 (05:00 - 10:00) [5:00]

So now let's add some type hints to our function parameters. This is where uh type hints really start to become useful. So for our create user function, we can specify that first name and last name should be strings just like we saw before. So I'll go ahead and add that in. And we could specify that age should be an integer. Now I know that we're getting some errors down here right now, but let's ignore that for now. Uh so basically what we are telling anyone who uses this function including ourselves exactly what types of values we expect for each parameter and we can also add a return type annotation to specify what type of value this function returns. Uh we do this with an arrow here after the parenthesis. So I'll go ahead and add an arrow here and say that we are expecting a dictionary of a return value. Now, for this email here inside of our function, again, I personally don't use these variable type hints much unless it isn't perfectly clear as to what the variable is. But for this email, we can immediately see that this is an fstring. So, I wouldn't worry about adding a type hint of string here personally. So, now that we've added these basic type hints, uh, let me point out that I'm getting a my pi error down here for our age parameter. And that's because we're saying that age should be an integer, but we're also giving it a default value of none since it's optional. So age can be an integer or it can be none. So in order to tell the type checker that age is optional, uh we can use what's called a union. And to do that, we can just use this pipe character here. And that is symbolic for or. So we're saying this can be an integer or none. Now before Python uh 310 I believe uh we would need to import the optional type for this uh since you might see it in other people's code. Let me show you that really quick here. So we would have to actually import this from typing and that is going to be sorry this from typing. We want to import optional and then we would use it like this. We would say that our integer instead of integer or none uh we would say that this is optional and then we would pass in an int type there. And that's how we would use that. You can see the way that I have my IDE set up. I have uh Ruff point this out to me and tell me that uh that this is the newer way to do these type annotations. Uh but this is how you might see it if you're looking at some older code. So I'm just going to undo this here and go back to what we had uh before. But I will keep in this import here for a second and just comment this out uh because we are going to be looking at some more uh imports here in a little bit. Now, we can also be more specific with the dictionary that we're expecting to be returned here. Right now, we're just saying that we return a dictionary, but we don't have any expectations of the keys or the values to specify exactly what we're returning. Uh, we could say, so for example, I will say that our strings will be key or sorry, I got that backwards. Our keys will be strings and then a comma here. And then our values. If our values were all strings, then I could put string there as well. And now this says that we're expecting a dictionary returned with the keys as strings and the values as strings. But remember, our age can be an integer or none. And we can see that it's already underlying underlining that for us right here. So we need to use that same union that we saw before to add those possible value types. So for our values here, which is after the comma, this is for the keys. values. For our values, I'm going to put in that pipe character and say that these can also be integers and they can also be none. So now I'll save that. You can see that our warning there goes away. And I just have a code styling warning there. Okay. So what we've done here uh with this dictionary return here, I think this is fine for fairly simple dictionaries, but you can imagine with a complicated enough dictionary, this might get a bit excessive and crowd our function definition. There are a couple of different ways that we can improve on this. Uh one of the easiest ways is to use what's called a type alias. With a type alias, we're basically just creating a new name for an existing type. So for example, let's say instead

### Segment 3 (10:00 - 15:00) [10:00]

of returning this dictionary with the keys as strings and the values as either strings, integers or none, we instead just wanted to call a dictionary with that structure and that was called user or something like that. And this is super easy to do. So to do this, let me just go up here to the top. I'm just going to create something called user here. And I'm just going to set this equal to this type directly. So now we are setting this user equal to this type that is a dictionary uh with all those specifications that we saw before. And now we can pass this in as our expected return value. So now instead of returning this dictionary with a complex structure here, I'll just say that we're returning a user. And this is what a user looks like in terms of types. So, this is what's called a type alias. Now, this syntax I'm about to show you is a lot newer. It came out in Python 312. But just to be clear that this is a type alias, we can explicitly put type here before user. And that'll explicitly show us what we're using this for. We're using this as a type alias. And you can create type aliases for any type. Uh so for example if you frequently work with RGB color values represented with a tupole of three integers instead of writing you know tupil int int all over your code you could just create a type alias for that and you could say hey I want a type of and call this rb and set that equal to a tupil of integer integer. Now, using these type aliases is great for keeping our code readable, but it doesn't prevent mixups if a value with the same type is passed in on accident. Uh, so what do I mean by this? Well, let's say that we allowed a user to choose a color for their profile and we wanted these colors to be RGB values. So, we could add a parameter when we are creating our user. So right here after age, I'll just create a new parameter here and call this favorite color. And I'll say that this should be an RGB value or none. We'll make this optional as well. Set that to none by default. And let's also put this in the return dictionary as well. So I'll return uh with a key of favorite color and just pass in that favorite color of theirs there. Now we can see that my pi is already warning us here that this doesn't match our returned user type. This is why typins are useful because maybe this would have been a mistake. Uh but now I can say that no that's okay. Uh our uh users actually can have RGB values um returned as well. So uh those are included in uh users. So now let me go ahead and pass in a favorite color here to a user uh just so we can see that this works. So I'll say favorite color is equal to and this is a tupil of three integers. So I'll just pass in a color here and save that and let me run it and we can see here that now it's returning our favorite color here. Okay, that's great. Uh but now let's say that somewhere down the line we started using HSL values as well. If you don't know what that is, it's not important. It stands for hue, saturation, and lightness, and it's just another way to represent colors. Uh but it's also a tupole of three integers. So let's add that in. Let's say that was part of our codebase also. And we have this HSL and that is also a tupole of three integers. Now, our create user function still expects an RGB value. We can see that we specified that here. It expects RGB or none. Uh, but one of the developers might miss that and accidentally put in an HSL value. So, for our John Doe down here, uh, I'm going to pass in that same color as an HL uh, HSL value. So, I'll just say favorite color is equal to a tupil here. And this is three integers also. uh 206 10 and 48. And I'll save that and run it. And we can see that works perfectly fine. Uh we're not getting any errors in our output. And there's no problems with uh my pi. And that's because for all our program knows, uh these three integers here are RGB values. Uh it doesn't know any better. Uh even though our developer accidentally passed this in and it's an

### Segment 4 (15:00 - 20:00) [15:00]

HSL value. So to handle this, we can create a new type instead of a type alias. And that will solve this problem for us. So to do this, we'll need to import new type from the typing module. So up here where I'd commented this out before from typing, we are going to import new type. And now where we're creating these type aliases, we're instead going to create new types. So, the way that we're going to do this here is I'm just going to say that RGB and HSL here are going to be new types. And then these new types are going to be called something here. So, for RGB, we'll call this uh RGB. And for HSL, we'll call this HSL. And then we'll go ahead and cut this out here. And then paste in the type as the second argument here. And let me go ahead and grab that and put that in as the second argument there. So now with this new syntax, we're not just checking if RGB is a tupole of three integers. So if I point out the error here uh we can see or the error from my pi that is we can see argument favorite color to create user has incompatible type expected RGB or none. So now passing in this tupole of three integers isn't good enough. Now it's expecting us to actually say whether this is an RGB value or an HSL value. So, I'm going to paste that in there. And now, this is where our developer who made this mistake uh would realize his mistake because then he would come in here and say, "Oh, this has to be an RGB value, not this HSL value that I am passing in. " So, it's explicitly stated as you're passing that in. So, now if I save that, our my pi errors go away. I can run that and we get the same output that we got before. Okay. So now that we've added in um this RGB value here for our user, uh you can see that our user type alias is getting a bit more complicated and crowded here. Now we're saying that our values can be strings, integers, RGB values, or none. And that's going to be for any value of our dictionary. So if something like age gets changed into a string somehow during some processing somewhere then that won't be caught. So let me do a contrived example here where we convert that to a string within our function uh and pretend that we're doing some processing just to see what this looks like. So in here in our create user function, I'm just going to say that uh string age is equal to and we're going to cast age to a string here. And now I'm going to return that as our age here that should be returning a user. And you can see here that even though we're expecting a user to be returned, uh whenever we pass that in, we're not getting any my pi errors here. It's h it's um that's just fine. And that's because up here we're saying that values can be strings. So it's not checking each individual value. Uh it's just saying that any value can be those. So instead of using a type alias for our dictionary where we have to pass in possible types for all of the values, we can actually use a typed dictionary that allows us to specify the types for each individual key. So to use this, we'll have to import typed dict from typing. So right up here after we import new type, I'm also going to import typed dict. And now I'll replace our type alias for a typed dictionary. Uh and to do this, I'll keep our uh type there for now. And I'll just create this new typed dictionary above uh what we currently have. So to do this, this is going to look like a class, but we're going to inherit from type dict. And within here, we can specify the value or the um types of every value. So I'm going to say that we're going to have a first name, and that is going to be a string. We are going to have a last name, and that's going to be a string. And I'll just keep going down here with uh every key and every value. So age can be an int or none. And we have a favorite color here and favorite color can be an RGB value or none. So now that we're using this, I'm going to delete our old example here

### Segment 5 (20:00 - 25:00) [20:00]

and save that. And now you can see that we are getting a my pi error here. Now that those values can be individually type checked. So it's saying hey we have an expression that's a type string here and the type dict of age has a type of integer or none and you're giving and you're returning a string. So that's exactly what we wanted. We wanted that error to pop up. So if that got um casted or converted in some way during some processing uh then now it's pointing it out to you. So that's good. So I'm going to go ahead and uh undo that now that we showed that example. go ahead and return that as an integer and get rid of our uh string version of age there. Now, depending on what you want and what you're doing, uh you might have different options for what it is that you want to do. Right now, user is defined as a class, but for all intents and purposes, it's really just a typed hinted dictionary since it's inheriting from typed dict. Uh we create it like it's a dictionary. we access its keys and values like a dictionary and so on. But it might actually make sense to create a class out of user if we wanted to add some more functionality or possibly even some methods. And when it comes to classes, there are data classes that can use type hints to autogenerate common methods like the init method and things like that. So if you're working with existing dictionaries, you can use typed dict like we've done here. Uh, but if you're creating this from scratch, it might be better to use a data class. So, let me convert this to a data class just so we can see what this looks like. So, I'm going to remove our type dict here from our uh imports and remove that uh from inheriting from that. And now I'm going to import a data class here. I'm just going to say from data classes, let's import data class. And we're not going to change much here. Uh this basically has the uh same structure. All I'm going to do is add this data class decorator here above uh where we are creating this class. And also we can give default values now. So uh here where age can be an integer or none. I'm just going to say that our default value is going to be none. And also for our favorite color. So I'll say that our default value there is none as well. And now that we've created this data class, this is now actually a proper class. Uh it's just like a class that we'd create from scratch, but these data classes use these type hints to clean it up a bit and also adds in a lot of those common methods for us. Uh so now when we're returning a user, instead of returning a dictionary, we'd actually want to return a user class. So right here, instead of returning this uh dictionary, I'm going to return a user class. And let me go ahead and just grab uh all of these here. Sorry about that. And this is going to have more of a class syntax than this dictionary syntax here. So for our user, we are going to set all of these equal. Okay. And I know this is a little ugly right now. Uh my screen gets ugly sometimes when I'm using these uh multiple cursors and not cleaning stuff up properly. Okay. But now uh we can see that we're turning a user class here. It's very similar to what we were doing before, but instead of returning that dictionary, u we are just passing in all of these arguments here um to that class that we just created. And since this is a data class here and we are expecting a user to be returned, uh that should work just fine. So if I run this, you can see that works. We're not getting any myi errors. Uh so that's all great. Okay. So eventually with type hinting, you're likely going to run into a bit of code at some point uh where you want to use a generic type. So, generic types let you create code that works with any type uh while still keeping all of the type-checking benefits that we've been adding throughout this tutorial. So, for example, let's say that we create a function that returns a random value from a list. Now, this could be a random user from a list of users. It could be a random color from a list of colors, anything like that. Uh to show you what I mean, let me grab an example from my snippets file here really quick and paste this in so you don't have to watch me type all this out. So, let me paste this in here. And I'm going to move this import up to the top. And I'm going to uh move where we're getting our random values here. I'm

### Segment 6 (25:00 - 30:00) [25:00]

going to move those below where we are creating those users. So, let me explain those snippets that I just pasted in really quick. So, we're just importing the random class here. I uh created a new function here called random choice that right now just takes in a these items here. Right now, we're saying that these items are a list of users and we're going to return a single user. And what we're doing here is just returning a random choice from those list of users. And now down here after we've created our users, I'm going to go ahead and comment out where we are printing out those users. Uh so I've created a list of just two users here. Uh picking a rando user and printing that out. And also here I am creating a list of emails from our users and grabbing a rando email and printing that out. Now you can see that right now we're getting a myi error here because random. choice we are passing in a list of emails here uh to our random choice function and right now is just expecting a list of users. Now uh type hinting doesn't actually affect whether your code will run or not. Um so I can still run this and we can get our random uh user and our random email. Um but we are going to get this my pi error here uh saying just warning us that we are uh have incompatible types here. Now, another thing here in my IDE, if I hover over our random email here, actually, uh I have that turned off right now. Um but for autocomplete reasons, if I type in a rando email here and do like an autocomplete on this, we can see that it thinks that it is a user. It's giving us access to the age, the email, uh favorite color, first name. So, not only do these type hints uh help catch errors early on, but it also helps our IDE uh in terms of being able to autocomplete things. So, it's thinking that we are returning a user here. So, it thinks that random email is a user. Now, I like having that IDE functionality, but we need to change this so that our random choice function type hinting also accepts a list of almost anything instead of just a list of users uh and returning a user like we have right now. Right now, we are grabbing a random email. So, those are going to be strings. So, we could do a union like we saw before and say that our list could be a list of users or strings. and then we'd return either a user or a string. But this might be a helper function that we use all over the place in the future. So, we really want to be able to accept a list of any type and return that type uh from that list. And that's where generics come in. And there are a couple ways that you might think to do this. So, first there's a generic called any. Uh let's import that and see what this looks like. So from typing here I'm also going to import any and save that. And now down here I could say that this is a list of any and we are going to return uh any as well. Now if I run this we can see that it still works and I'm not getting any myi errors. So we might think that this is good. Now, using any can be good whenever you really don't know or don't care what the type will be. Uh you might run into that when working with external data or unvalidated JSON data where you really don't know what the types will be. But we're losing a bit of functionality in our IDE here. Um, so if I was to go back here and, you know, try to do something with rando user and now you can see that we're not getting any autocomp completion here. And that's because it doesn't know that this is a user. Um, so it doesn't know what this is. If I had my hover functionality on here, uh, then it would also tell us that this is of type any. So instead of using any here, uh what would likely be better is to use a generic called type var. So type var basically tells us that this could be any type, but it's going to be the same type throughout. So let me show you what I mean. So first we'll import that. So instead of any I'm going to import type var here and save that. And now down here instead of any we are going to use actually we are not going to put type var right there. Uh we are going to create this outside here. I'm just going

### Segment 7 (30:00 - 35:00) [30:00]

to call this t is equal to type var t. And now we can use this generic type var here uh instead of where we had put any before. So I'm going to say that this is a list of this generic type bar and that we are going to return that same generic. So now if I run this, we can see that it still works. Um I'm not getting any myi errors here. I'm getting a code styling error. I'll take a look at that in just a second. Uh but now if we try to use that autocomplete now you can see that it knows that this is a user here. And if I go down to random email, then it knows that random email is a string. So now it's given us uh the string autocomplete IDE features here. Um so let me go back up to our function. Let me explain again what we just did because this can be a little bit confusing. So before we were saying that we were taking in a list of any type and returning any type. So whenever we tried to use our IDE functionality, it thought that was any type. So it couldn't give us any help as to what that was. But here what we're doing is we're creating this generic type bar and we're saying that we're going to accept a list of basically anything. uh but when we return this value it's going to be that same type. So if we take in a list of users we're going to return a user. If we send in a list of strings we are going to return a string. So it's keeping these types consistent throughout and there's a connection here between the input and the output if that makes sense. Now, the code styling warning that I'm getting here, um, I believe what this is in Python 312, the syntax of this has actually changed and there's a shorthand that you can use now. We actually no longer need to import typear anymore. Uh, they cleaned this up a bit. So, let me show you what this looks like now. So I can actually remove type var here and I can remove where we are creating this generic type var and instead uh right after our function here I can put in the square brackets and put a t right there. So I know this might look a little strange but I personally like this. I think this new syntax is cleaner and the type variable t now is scoped just to this function which makes more sense. So basically what we're saying here with type hinting is we're saying hey this random choice function here we're type hinting that we have a generic type var here and we're going to pass in a list of a specific type like a user and we are going to return that same type. In this case, we're going to return a single user or if we pass in a list of strings, we are going to return a single string. And you can see now that I've updated that, our code style warning goes away there too. So that is the newer uh Python 312 syntax um that you probably want to start using if you're using uh the old syntax. But if you're looking at older code, I still wanted to show you that so that you can understand what you see in some older code as well. Okay. Okay, so now I'd like to cover using type hints with thirdparty packages. Uh, a lot of thirdparty packages don't include type hints. Uh, but there are often stub packages available. So, let me show you an example using the request library. Uh, so first I'm going to add this to my project here. So, within terminal, I'm going to say uv requests here and add that to my project. Okay. And now let me grab a small snippet of code uh where I'm making a simple request and checking the uh status code of the response. So I'm going to go ahead and just grab this here and I'll just paste this in towards the top. So up here at the top I'm importing request making a request to my personal website have a timeout of 5 seconds and then just grabbing that status code there. So if we look at the mypi error here, myi is telling us uh specifically that it doesn't have stubs installed for requests. It'll treat all of these types as any and not give us proper warnings. So for example, this status code here returns an integer. Um so you know 200 400 things like that. So if later down the line if I try to uh change this status to something like okay because I didn't know that was an integer then I would want my pi to

### Segment 8 (35:00 - 40:00) [35:00]

tell me uh that we are res reassigning an integer to a string but right now I'm not getting that warning because it doesn't know those data types. So to solve this what we need to do is install the stubs and this will be like installing any other package. Myi is even being uh telling us exactly what to do here. So it's giving us the pip install instructions and its output. Now these stubs usually have the pattern um types. So we can see here that this is types requests. So it usually looks like this. Let me it's usually going to be types and then whatever the name of your package is there. So for requests, what this is I'll just do a UV add. This is types dash requests. So I'll go ahead and install that. And now let me see if that's giving us I might need to restart my server here since I'm using the extension. Let me do my pi restart server. And that should now There we go. We can see now it knows the data types that we can expect from different requests and using this library. So now it knows that status code is an integer and now it knows when we're reassigning this to a string it's saying hey uh we're giving this a type string but it has a type integer. So that's exactly what we wanted and that will you know find errors for us uh more quickly while we are doing our programming. So then I can just come in here and delete that or change it uh however we wanted to do that. So that's something that you might run into if you're using thirdparty packages in your code. Uh so if you're using requests pandas stuff like that and you're using type hinting in your code, uh you're going to want to install these stubs. Okay. So to wrap things up, let's talk about some best practices and some tips for you to start using type hints. So first of all remember that using typins isn't all or nothing. You can start small add them to new functions that you write. Uh use them in critical parts of your application to self-document the code and catch bugs earlier on. And you can gradually add them to an existing codebase over time. Uh you don't need to do entire modules at a time. You can just add them to single functions and variables and things like that and just add them as you go and commit a little bit just build them up over time. As far as some best practices go, inputs should be as generic as possible and outputs should be as specific as possible as a general rule of thumb. So let's look at our random choice function here really quick to show you what I mean. So for our input here, we tried to make this input uh more generic to accept more types of inputs that may be passed into this function. Instead of limiting ourselves to just a list of users, uh we changed it so that we can accept a list of basically anything as long as it matches our output here. And we could have even made this more generic if we wanted. uh instead of just accepting a list of any type, we could have accepted an iterator of any type for example. Uh that way if our program changed and then we needed to grab random values from a tupole or something like that, then we'd be able to do so. So that's basically what it means about keeping inputs generic as possible. Now if we look at our create user function here, we can see that as we went through the tutorial, we got more and more specific with our output. We started off by returning an untyped dictionary. Then refraed it to return a dictionary that typed the keys and the values. Uh then we moved to a typed dictionary that had the types for the individual values. And then we finally move to a data class that has typed attributes. So we got more and more specific with the output that we were expecting. So I hope that makes sense. Uh so this should have covered a lot of different use cases for type hinting and give you an idea for how you can start using this in your code. Now we didn't cover everything. Uh but this is an extremely broad topic. If there's anything specific that I didn't cover that you were hoping that I would here, uh be sure to let me know. Now, in a future video, I'm going to be covering Pyantic. Pyantic is a library that uses types to do runtime validation. It's used a lot in web frameworks like fast API to validate incoming data. And I'm also finishing my Async. io video. I know that that's a highly requested one. Uh, but I keep changing the examples of what I want to use and the animations that I'm creating for that video in order to

### Segment 9 (40:00 - 40:00) [40:00]

really get the points across that I want to get across. Uh, but it's getting there. Uh, stay tuned for that. I hope to have that done shortly. But I think that's going to do it for this video. Hopefully now you have a good idea for how you can use type hints in your Python code to improve your code quality and catch bugs earlier on. But if anyone has any questions about what we covered in this video, then feel free to ask in the comment section below and I'll do my best to answer those. And if you enjoy these tutorials and would like to support them, there are several ways you can do that. The easiest way is simply like the video and give it a thumbs up. Also, it's a huge help to share these videos with anyone who you think would find them useful. And if you have the means, you can contribute through Patreon or YouTube. And there are links to those pages in the description section below. Be sure to subscribe for future videos. And thank you all for watching.
