# This Amazing TypeScript Feature Has NO Docs!

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

- **Канал:** Web Dev Simplified
- **YouTube:** https://www.youtube.com/watch?v=Xm_VGeTpS2Q
- **Просмотры:** 53,585

## Описание

FREE TypeScript Utility Types Cheat Sheet: https://webdevsimplified.com/ts-utility-types-cheat-sheet.html
TypeScript Simplified Course: https://courses.webdevsimplified.com/typescript-simplified/?utm_source=youtube&utm_medium=video-description&utm_term=video-id-mXpE2v0whiI

TypeScript is overall well document, but one of my most used features in TypeScript doesn’t even have a documentation page. In this video I will be covering the satisfies keyword in depth and showcasing why it is something I use in every single TypeScript project I write.


📚 Materials/References:

FREE TypeScript Utility Types Cheat Sheet: https://webdevsimplified.com/ts-utility-types-cheat-sheet.html
TypeScript Simplified Course: https://courses.webdevsimplified.com/typescript-simplified/?utm_source=youtube&utm_medium=video-description&utm_term=video-id-mXpE2v0whiI


🌎 Find Me Here:

My Blog: https://blog.webdevsimplified.com/
My Courses: https://courses.webdevsimplified.com/
Patreon: https://www.patreon.com/WebDevSimplified
Twitter: https://twitter.com/DevSimplified
Discord: https://discord.gg/7StTjnR
GitHub: https://github.com/WebDevSimplified
CodePen: https://codepen.io/WebDevSimplified


⏱️ Timestamps:

00:00 - Introduction
00:30 - Basic satisfies Keyword
03:27 - Use Case #1
06:13 - Use Case #2
08:05 - Use Case #3


#TypeScript #WDS #TS

## Содержание

### [0:00](https://www.youtube.com/watch?v=Xm_VGeTpS2Q) Introduction

There's a feature in Typescript that's so powerful I use it in every single project I create, but it doesn't even have its own dedicated documentation page. In this video, I'm going to be going through multiple examples of exactly how this feature works in realworld code. But that's not all because at the end of the video, I'm going to be sharing this exact example, which is the example that really revolutionized how I think about type safety in general. Welcome back to WebDev Simplified. My name is Kyle and my job is to simplify the web for you. And before we start

### [0:30](https://www.youtube.com/watch?v=Xm_VGeTpS2Q&t=30s) Basic satisfies Keyword

diving into these advanced examples, we first need to understand exactly how this feature works in Typescript. And to do that, we need to look at the problem that it solves. In this simple example of code, I have an object type up here, which is a value, which is a string or number. I'm currently not using this anywhere, but we will in a second. Next, I have a variable we just called a that has a value that is a string. And then I'm logging out that value, and I'm just taking that value and converting it to an uppercase value. that works perfectly fine. But I want to make sure that this a object follows this exact syntax of a value that is either a string or a number. Now, if I were to come in here and I spell value incorrectly, I don't get any errors on this object cuz it's not hooked up to this object type. So, normally when you see something like this, you just say, okay, I'm going to type this variable as the object type. And now you can see I immediately get an error because it's spelled incorrectly. If I spell this correctly, you can see the error here goes away. But I now have a new error. You can see down here my value says to lowercase does not exist on the type of string or number. Again that's because my value is a string or number. Now in my case I know that this a object always has a value which is a string. Which is why when I didn't have this typed I was getting no errors because it knows value is a string. But by telling Typescript that my type of this is my object type here it's saying okay I know that this thing right here is a string but I don't care. I'm overwriting the specific type of this with a more general type that is a string or a number. And this is a bit of a problem because I want the type safety of knowing that this is an object, but I want the flexibility to say, oh, this value is specifically a string in the case of my a object here. The only way to fix this particular problem is by using the satisfies keyword in Typescript. So the satisfies keyword usually goes after whatever your value is. And you're saying that this value satisfies a specific type. So in our case, we type in that satisfies keyword and then we type in the type we want this to satisfy. So in our case, we're going to type in that object type just like we had before. You see that we have no errors. So already we're off to a great start. But if I try to spell my value incorrectly, I'm going to get an error. And the reason I get an error is because I have this object here. And this object must satisfy a specific type, which is our object type. So it must match the type that we have up here. But of course, I have this misspelled. So it does not match that type. So we get that exact same type safety of when we said that a forced to be that specific object type. But in our case, all we're doing is we're saying, hey, we have this specific object right here. And all we care about is that it satisfies this particular type. Nothing else about it. It doesn't change the type of this particular object. So if we bring this back to how it was before, you can see we get rid of all those different errors. If I try to turn this into a boolean, I'm also going to get an error because again, this must be a string or a number. We can bring that back to what we had before. And best of all, you can see that this a variable for the value is always a type of string because it's using the more specific version. So the satisfies keyword in the most general sense is used when you want a value or an object to maintain its more specific type while also conforming to a more general type. We want it to maintain the type here of string while conforming to the much less specific object type right here. Now this is a very contrived example. So let's move into a real world use case of this. The

### [3:27](https://www.youtube.com/watch?v=Xm_VGeTpS2Q&t=207s) Use Case #1

first one here is when you have a complex object type. For example, here we have this complex options which has a ton of different things we can specify and most of them as you can see are entirely optional. The only thing that's required is the mode which must be simple or advanced and then we have a bunch of other stuff down here. Now you usually will see this in a library where it has a bunch of options you can pass in and you have a function that takes those options. In our case, this function doesn't do anything. It just takes in that option type right here of the complex option. And you can see down here I call that function and I can, you know, get all the different type safety. I can get my level and again I get type safety for all the different properties for this. If I spell something incorrectly I'm going to get errors for that. Everything works just like I expect it to. But often times these options get really long and complicated and what you generally want to do is you want to take that out and put it into its own variable something like this. And then you pass your option in like this. Now you can see I am getting some errors inside my code. The main reason for those errors is because this option is essentially using a string here for the mode a string for the format. If I were to just throw an as const on here, that does get rid of the errors because as const essentially forces it to have a type of the exact string I pass along, not a string in general. But that's not really the thing that I'm trying to solve with this. By extracting this option out into its own type, it makes it easier for me to write my code cuz now everything is in one single place. But the problem that I run into when I do this is that now I don't get type safety. If I were to, you know, make this incorrect and put a string here, I don't get type safety on my option. Obviously, I get type safety down here, but that's a little bit late. Also, I don't get any autocomplete. You can see there's no autocomplete on anything that I type into this, which is again another huge problem because it makes writing out my code much more difficult. If I want to change this from simple to advanced, again, no autocomplete at all. I just had to guess that I want this to be advanced and it doesn't, you know, give me anything at all on what this specifically should be. This is a great use case for that satisfies property. I can come in here and I can say that I want this to satisfy specifically my complex options. Just like that. And now I don't even need the as const or anything else. Typescript is smart enough to know that this option matches the complex options type because of this satisfies keyword and I get full autocomplete. You can see here simple advanced and so on. But the really great thing about this is it keeps my type really specific. It doesn't widen that type. So when I say option oops option dot you can see I only get my format, my level, my mode, my nested and my retry cuz those are the things that I specified. If I were to change this to, for example, come up here and type this as complex options. You'll notice that when I come down to my options section here and I look at this, you can see here I get a bunch of different information. I get the format, I get the level, I get retry count, things that I didn't pass along. And also, for example, things I did pass along like retry count, they're actually optional. You can see it says it could be undefined. So, it widens my type when really all I want is as narrow a type as possible. So, this is a perfect use case for something like the satisfies keyword. and I use it very often when I want to take an object and essentially extract it out into its own type of

### [6:13](https://www.youtube.com/watch?v=Xm_VGeTpS2Q&t=373s) Use Case #2

thing. The next example I want to talk about is essentially just expanding upon this even further with narrowing our types. In this particular example, we have an RGB type which is a string that starts out with the pound symbol in front of it or it could be a set of three specific numbers in like an RGB format. And finally, we have primary colors of red, green, and blue. Now, this colors object that I have here, I want essentially to be a record that has my red, green, and blue color, as well as the color definitions for them in RGB. So, you may think, okay, we're going to come in here with a record. The record type is going to be our primary color, and those primary color values are RGB. Now, immediately when I do that, you can see that does catch the errors that I had cuz I actually had lots of errors in my code. For example, this string needs to have a pound sign in front of it, and this blue value needs to have another number inside of it. And of course, I spelled green incorrectly. And I added this additional wrong type onto here. So I had a bunch of different errors that adding this little bit of code helped me catch. But by adding this, I actually added new errors into my code down here. You can see that my red color is a type RGB. I know that it's a string based on this particular line of code right here. But again, since we're making this a more wide type, it is less narrow. It now doesn't know that. So again, all I need to do is just take this exact code and replace it with the satisfies keyword. The satisfied keyword keeps my very specific type for my colors. You can see when I hover this, it gives me that very specific type, which means when I use it down here, I make sure I get all the goodness of having those specific types. But if I were to do something like spell green incorrectly or use my red type incorrectly, I'm going to get errors for both of these, which is exactly what I want. Now, before we jump into that final example, I do want to mention if you're confused by some of these advanced TypeScript things, such as the satisfies keyword or how I'm doing this template string literal right here, I'd highly recommend checking out my full TypeScript course. I'll link it down in the description for you. It covers everything you would ever need to know about TypeScript. Also, if you're unfamiliar with these utility types like record, pick, omit, I have a full cheat sheet that's entirely free. I'll link that in the description as well. Now

### [8:05](https://www.youtube.com/watch?v=Xm_VGeTpS2Q&t=485s) Use Case #3

moving on to this final example. This is by far the most common way I use the satisfies keyword, and I absolutely love it. In this particular case, we have this grade type here, which is just an enum essentially, A, B, C, D, or F. And we have a function called get grade description. You pass it in a grade, and it returns a string for all the different grades that you could possibly have. You can see here I'm calling this with A, B, C, D, and F. And when I go ahead and I actually run this code, so we'll just run that grade. ts. You'll notice the output here I get is excellent, good, average, below average. And then for F, it's returning undefined. It should be returning some type of string like failing or something like that, but it's returning undefined. And that's because when I wrote my switch statement up here, I forgot to add the case for F. Now, this is something that's very easy to do, and especially if I come along and say, you know what, there's a new grade. We're going to add an S-grade into this. Now again, I need to go back and remember all the places that I used this switch statement for my grade and update every single one of them. That's really hard to remember, especially if you have thousands and thousands of files of code. So instead, what we want to do is we're going to add a default type to the very end of this. This default type is not going to do anything other than throw an error or whatever you want. I generally just throw an error. So we'll say throw new error, invalid type, just like that. We'll use string template literal just so we can embed this directly into there. and we'll say grade and we'll say invalid grade. There we go. So now I'm just throwing an error that we have an invalid grade. So at least when I rerun this code, I'll get an error now instead. You can see I get a giant error essentially saying invalid grade F. But what I want to do is I want to add type safety to this forcing me to define all my different cases. To do that, all we can do down here. Our grade right now is the value F. You can see it's clearly the value F cuz that's the one that I forgot. What I can do is I can add a satisfies onto here. I want to say that this should satisfy the never type. And the only way this will satisfy the never type is if I make sure I cover every single one of my cases because if they're all covered already, then this should never be executable, which means my grade will be a type of never. Now, in my case, it's not a type of never. So, I get an error right here in Typescript immediately. That lets me know, hey, I forgot to add one of my cases. In our case, I forgot the F case. So, let's just return something like failing. There we go. And now you can see that this grade for satisfies never is correct. And when I hover the type of this, you can see it is the never type. If I run my code, everything should be working. You can see it returns all my different grades. And again, if I add a brand new grade, let's say s onto here, it immediately throws me an error everywhere in my code where I put this satisfies never. I don't write any switch statements anymore in Typescript without having this satisfies never at the end because it makes sure that I will always come back and update my switch statements anytime the enum or value that they're based on changes. And this technique really helped me rethink how I look at type safety because now I really try to focus on making my type safety a compiler thing that really will throw me warnings or errors whenever I change my code. I almost view it as a refactoring tool. When I refactor places in my code, I immediately want to get changes in my TypeScript or errors in my TypeScript telling me where those problems are. And this satisfies keyword in combination with switch statements makes this incredibly easy for this style of code. Now, as I mentioned already, if you want to learn more about TypeScript utility types, I have a full cheat sheet that covers everything you could ever want to know. I have it both in light mode and dark mode. It'll be linked down in the description below. And I also have my full TypeScript course which covers everything you need to know from absolute beginner to intermediate level TypeScript. That'll be linked in the description as well. With that said, thank you very much for watching and have a good

---
*Источник: https://ekstraktznaniy.ru/video/20683*