Making TypeScript Stick

Template Literal & Key Remapping

Making TypeScript Stick

Check out a free preview of the full Making TypeScript Stick course

The "Template Literal & Key Remapping" Lesson is part of the full, Making TypeScript Stick course featured in this preview video. Here's what you'd learn in this lesson:

Mike demonstrates that template literal types build on string literal types and can expand into many strings via unions. Key remapping has been given a new syntax to allow the transformation of keys in a more declarative way.


Transcript from the "Template Literal & Key Remapping" Lesson

>> The next very exciting language feature that has landed in TypeScript recently is much more than it seems. Template literal types. So you can think of these as sort of the type equivalent to those backticks strings that let us interpolate values into string templates really easily and the syntax is in fact the same.

So good news there. Just remember when you're working in value space versus type space, are you on the left hand or the right hand of the =? So on it's surface it seems that we can use this to create strengths. So for example you can see here, this here could be either median or mean, and it's followed by value.

And we can in a nice, concise way get both of these, optional number properties. We can get both of these on this stats object instead of having to type them one at a time. So one advantage here is less code to worry about another is you could have a source of truth that has this list of things.

And you can enforce with the type system, a convention that we have these value types like median, mean, and mode. Standard deviation, you can have all of these and then it always is followed by the word value. So you get this nice consistency because, in this case, we're using this.

Anyone remember what this is called, by the way? The second line, there's a name for this called a map type, it's kind of like the type version of a for loop. Where we're iterating over a list of keys and defining the value that can be found on each key.

So we're kind of almost like we're looping over an array of these things, and then we're transforming them a little bit. And then that's the value. So it allows us to sort of build things up in a very consistent way. So, this is the most superficial use of a template literal type, but they can do so much more.

So here we're using this extract type, which lets us take a portion of a type right. We would say, key of window. So this would be a whole lot of strings. Any function name, any property name, like document will be in this list. Window.document, right? And then what we wanna do is get the sub part of that list that matches another type.

So in this case what we're saying is give me a subset of the names of everything on window that begin with the word set. And the key thing that we're able to do here is we can put in any they're so set followed by anything. It's almost like a wildcard, right, like set star.

So it's not just about assembling a specific string using using a list of prefixes or suffixes. You can actually put a lot of different things in here and use these template literal types in some very creative ways. In fact you could, you could get the first letter of a string literal literal type by saying you know it's any.

Followed by another any or something. And infer like extract out the back half of the string. You could split a CSV by saying there's something, something and give me that piece and then followed by a comma. Another way to think about this, if you've ever written a regular expression, you know how you can have these capital groups where you'd say, there's an email address give me everything before the @.

So that is kind of what's happening here. It's one possible use of this type. So again, more than it seems this is more than just like a convenient way to build up strings. With template literal types we get three utilities that frankly are only useful in this kind of context, and they're used to transform string case.

So we have a capitalized, we have an uppercase, we have a lowercase. It's a good thing that TypeScript gave us these because there is no way to express these types using TypeScript code. So if you go all the way down and to see how do they internally define these types.

You'll see the word intrinsic there, which just means it's like at the compilers keyword for hand waving. It's like don't worry about it. We got this handled in the compiler somewhere, like we do something special every time we see capitalized. This is unlike some of the other utility types where if you drill in and you're like, how does this thing work?

You can see it's built using TypeScript, these. It's there's just no way to do it. So it's good that they gave it to us. But you can see here, we could build a nice little event API, where we can try. We can have these keyboard and mouse events.

And we can either capitalize, which of course, makes the first letter capitalized, or this is all uppercase. And this is all lowercase. And you can see here I've added some things to lowercase in that last example. So we're about to dig into a challenge and get hands on with this.

You will need to use these three types in order to create a nice semantic API based on some names and things. A complimentary feature two template literal types is key remapping. So again, remember that a mapped type which is anytime you see sort of K in or you can use whatever letter you want here.

But it's sort of like a four of loop. Think of it that way. So it's like for each key in a list of keys that's our loop. Well, this syntax here is the new piece. This is the new thing that landed in TypeScript 4.2 and that is allowing us to remap.

So you can see here we have red, green and blue. Those are our colors that effectively is what we're iterating over. So K is gonna be first red, and then green, and then blue. And what we can do is transform that key. And we could say, I want this to be select and then capitalize the r in red and that's how we ended up with select red down here.

This was in theory, possible in some way. In older versions of TypeScript but you would have needed to have some explicit let's say listing of a mapping between like red and select red and blue and select blue. You would have had to write that in your code and you would have gotten some help from the type checking.

That would have enforced that you have an entry where you must have an entry. But this is a lot cleaner and it saves you from having to have all these intermediate types where it's sort of extra backflips that you have to do.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now