Check out a free preview of the full React and TypeScript course:
The "Utility Types in React" Lesson is part of the full, React and TypeScript course featured in this preview video. Here's what you'd learn in this lesson:

Steve discusses some of the utility types built into React and TypeScript including keyof, unions, intersections, conditionals, exclude, extract, string manipulation, objects, pick, omit, React.HTMLProps, and React.ComponentProps.

Get Unlimited Access Now

Transcript from the "Utility Types in React" Lesson

[00:00:00]
>> So we've talked a little bit about some of the utility types, that are either built into TypeScript or built into Reacts types. This is not an exhaustive list of all the utility types. There are a lot more than a lot more built into TypeScript, you can go through the docs and see.

[00:00:14] We're just gonna cover some of the ones who might, there were most often to likely find while dealing with React. The first one is this idea of Keyof. And keyof allows you to basically get all the keys in a given type. So you think about like object keys in JavaScript, this one will get you just all of the keys an object in a union type.

[00:00:37] So if you wanted to get just all the names of a prop on a given object, keyof will allow you to do that. We'll actually use this to figure out like, when an object like the table rows on a character card we'll see in a little bit. I only want to let them specify a known property on that to pick out what we want to show on the table row, we can use key I've defined that as well.

[00:00:58] If you just need to get a single one, you want to get the value of a single key and an object. So you can use a bracket notation that we've seen in JavaScript before. So prop0 will get us the type of C. Again, if that was a string or a number, it would be string or number.

[00:01:16] Numbers or work, if you wanted to get two, you can just use a union type in there as well. And again, it's a way to kind of effectively met a program with our types. If you want to get all the values, there isn't necessarily a built-in helper for that.

[00:01:31] If passing in a union of keys, will get you multiple keys and saying, okay, passing all the keys will get you all the values. So here you can see we've got this type of obj. If we say, go get me the values of all the keys, we'll get all the values.

[00:01:50] Sometimes it'd be clear, there are things that you used to have to write your own utility tests for them, they're not built into TypeScript. So I wouldn't be surprised if that changes in the future but as of TypeScript 4.2, that is absolutely the case. Unions we've seen but never really talked about directly, which is you have a type A that has a, b and c, right?

[00:02:13] It can be either a, or b, or c. But you can also do that across two different types. So we say it can either be the type of A or the type of B. Well, now you get everything kind of in both of them. The interesting part in the reason that I bring this up, cuz unions will be anything as isn't either one of them, but it's kind of the opposite with objects.

[00:02:39] So if you unioned objectType A and objectType B, the only one that would be in here is this idea of sharedProp, because it's the only one common between the two. Intersections for raw values are only the ones that appear in both types, but you actually saw us use this with a pizza state before with objects that will actually combine them together.

[00:03:02] So with the objects it will allow us to say like, okay, everything is one plus the other one. So they act opposite, objects versus primitives. I don't really get to make the rules here, I just have to try my best to explain them. So for primitives, a union will be anything that's neither one of them, but for objects is only the shared properties.

[00:03:23] An intersection in the case of this ampersand that ends between A and B on that last line is only once common, but if you do it two objects it will create a combined object of the two, I don't make the rules. We're not gonna get into this but like you might see it when you hover over some of the ones in React, is you can use conditionals but it's only ternary to figure out, okay, this is one if it has a property of a length and that's a number, cool, rapid, an array, otherwise give me back the object to itself.

[00:03:56] We're not gonna use it directly, if you needed to get really sophisticated types you could, but you we will see it when we hover over some. So if you see like weird question marks and colons, they are effectively the weird question marks and colons that you know and love from Terry's, they're just in your types as well.

[00:04:11] And here's an example of what that might look like. This is purely one that the types will actually be only true or false. But it's a way to look at both the generics and the ternary which is if you look at that result1, if 1 2 and 3 extends B so 123 is of anything as a number, is 1 2 and 3 a number?

[00:04:32] Yes, that would come out as true, otherwise it would be false. All right, this one's kind of interesting. So exclude actually uses one of these Turner's, right, but it's built in to TypeScript. So you don't have to write an exclude utility helper yourself, cuz it's built into TypeScript.

[00:04:51] But if you wanted to, this is how it would work. So we've got, hey, we got this type, it's either 1, 2 or 3 and we wanna exclude 2 as that second argument there. Cool, you get a new type that has 1 and 3. You can also again is that extend.

[00:05:05] So we've got 1 a 2 b, I wanna exclude anything that's a number that'll work. Or if you wanna remove one union for another one, it's one of those things where you would use it every day, no. Is eventually gonna be something that you need to just have in your mental framework for when you need to say, okay, I need everything from this other type except for one value.

[00:05:30] Absolutely, if there's certain values that we don't wanna pass to a smaller component, so on and so forth and I do generically. This is again, something that is somewhat useful to have available to us. The opposite of exclude is not include, cause that would be too easy. The opposite of exclude is extract which, again, if this will pull out only the numbers or only the ones that you're looking for.

[00:05:57] Again, I don't make the rules here, I just explained them. A pick allows you very much I pick in lodash. Takes one type, and allows you to just pick the keys that you want. So if you wanted, only certain keys that have another type, you can dynamically do that as well.

[00:06:15] And it's got a friend called omit, right, which is okay, take all the properties of this type and just don't pick these 1 or 2. This will actually be super useful for us in a lot of ways which is like okay, hey, I'm gonna define a custom button.

[00:06:31] Take all the properties out of a button except for the ones that I'm gonna define myself, right? And I will allow you to do that with your reaction components as you wrap them. And we also string manipulation. If you need to change some of the casing on a given string type, there are actually utility types built into TypeScript that allow you to take a given value, a given string make it all uppercase or lowercase, whatever you need to do.

[00:07:02] Some of the React specific ones. So React to HTML props and it takes this generic of some HTML element, will give you a type representing everything that is built into that native HTML DOM node. So if you want to create your own input field and you don't want to necessarily copy all the props of that an input field tax according to the spec, this will be like our props, you have that ampersand and then everything that a HTML input element can do as well.

[00:07:34] And so now it will be our special input props, plus the everything that's an element. So before we have those range sliders and those range inputs, right now they will not take everything that an input took. However, we could theoretically and arguably should go in and say, okay, adjustment input props are the special things that we wanted, cuz label is not one of them for instance.

[00:07:59] Plus, everything that an input field does and we'll pass them all on through. This is incredibly powerful if you're building a component library, or a large enough application that you're building a large enough React application is effectively its own library, cuz you're using pieces of it throughout the application as well.

[00:08:16] And finally, React.ComponentProps. I believe we saw this one a little bit earlier. We'll use it again allows you to take any given React component, and figure out its type. This is also useful. Let's say, before we would do an export type or whatever. Let's say a component didn't export the type, you can actually kinda figure out what it was or you pass in a component you get its type, and then it will pull out the prop type itself and allow you to kind of read the type of another actual component that you're using in React.

[00:08:49] So this is some of the utility types that we can use in our React applications.